Posts in Machine Language
如何在64位win10的VS2017环境下搭建汇编环境
- 18 June 2018
用户AcmeContracted安装masm32失败,所以想知道是否能集成masm64到Visual Studio 2017中。
VS里面masm不是单独的,是C++工具集的一部分,而在VS2017里C++工具集不是默认安装的,所以要先安装C++工具集。
PIC 16F88 Microcontroller Servo Controller Project
- 25 July 2005
1) Introduction
The goal of this assignment is to control the position of a servomotor by generate pulses on the output pin for a time specified by various voltage of the input pin of the chip. The voltage should also be displayed by a 7-segment LEDconnected to some output pins of the chip.
2) Overview of the PIC 16F88 Microcontroller
PIC16F88 is a member of the huge Microcontroller Chip Family with 16 I/O pins and 2 power pins. It contains a lot of functions which are abundant to this project. The essential features used by this project are · Programmable Flash
· Data Memory
· Interrupt
· Internal clock and multiple time modules
· A/D Module
Information of other features, such as EPROM access or power management, can be found in the datasheet of this chip, which is available at www.microchip.com.
a) Programmable Flash
PIC16F88 has a 13 bit program counter, which can address 8K*14 addresses, or up to 1FFFh. However, it is paged so that accessing above 4K*14 will cause a wraparound. That is, the actual address is the address masked with 3FFh. The size of the code in this project is far from this limit, however. The starting address after power up, named Reset vector, located at 0000h. The interrupt vector, called by the chip when an interrupt occurs, located at 0004h. Stack memory is hardware implemented, and is indirectly manipulated by some instructions such as CALL and RETURN.
b) Data memory
Similar to IBM-PC, data memory is divided into several parts, called Banks in this chip, and a bank selection must be made before accessing an address outside current bank. Each bank has a 128 bytes extent, and some of them are mapped to the same position for convenience. The lower part of bank is reserved for Special Function Registers, and above them are General Purpose Registers, implemented as static RAM. To reduce bank selection, this project use 70h-7fh, the General Purpose Registers mapped to the same position in every bank. Some Special Function Registers are also accessed to perform tasks such as A/D I/O or timing. Accessing to these registers will be discussed later.
c) Interrupt
An interrupt is generated when predefined condition met, and the chip will make a call to the interrupt vector located at 0004h in the Programmable Flash. Some special flag bit in Some Special Function Registers are set before this call. This project use the A/D, Time0 and Time1 overflow interrupts for asynchronous operation. The general tasks of the interrupt handler are 1. First, disable all interrupt to prevent reentry
2. Save context information, such the value of W register, the Status register and program counter.
3. Check desired flag bits to see if the reveal the desired type of the interrupt occurs, and handle it with the flag bits cleared for future handling.
4. Restore context information to enable the program continues as usual after the interrupt occurs.
At last, enable interrupts to enable future interrupts
d) Internal clock and multiple time modules
The chip comes with 3 timer modules, and 2 are used by this project. TMR0 and TMR1 are prescalable timers with different ranges. The TMR0 register and TMR1H/TMR1L are readable and writeable counter register for these two timers, along with the Status register for synchronous operations. Interrupts are also generated when these counters overflow, and this project use them to invoke asynchronous operations and generate signals with varied time interval.
e) A/D Module
The chip comes with a 10-bit, 7-channel Analog to Digital module to convert input signals to 10 bit digital number. If the module is configured properly, after a flag bit in the ADCON0 register is set, an A/D conversation begins, and when it finishes, the result is placed into A/D result registers, namely ADRESH and ADRESL, and the flag bit is cleared. An peripheral interrupt is also generated to allow asynchronous operations
3) Description of the test circuit
Here is a block diagram in the assignment guideline of this project. Connection specification:
Pin number |
Description |
Connected to |
17 |
A/D input, 0-5V |
Variable voltage |
18 |
Digital output, 33HZ signal |
Servomotor |
6-13 |
Digital output |
7-segment LED |
5 |
Ground reference |
Ground |
14 |
Positive supply |
Power |
4) Development of the control program
This program is divided into following modules:
Initialization module
Port A Configuration
Port B Configuration
Frequency Setting
Interrupt Setting
Interrupt handler modules
A/D Interrupt
TMR1 Interrupt
TMR0 Interrupt
With the reset and interrupt vector fixed, the program placed a jump instruction at the reset vector, and the destination of the jump is the actual beginning of the program. The program then calls the initialization module, and then enters an infinite loop and is ready for interrupts.
a) Initialization module
This module is spitted into 4 modules. These modules are independent, so they can be composed into one, but they are separated for easier debugging and understanding.
i) Port A Configuration
The task of this module is to set analog input and digital out pins. TRISA register is set to 1, indicates the pin RA0 is set to analog input, and the rest pings on PortA are set to digital output. The ANSEL register is also set to 1 to select RA0 for A/D conversation, and the ADCON0 is set to b’11000001’ in accordance. After the configurations are finished, the first A/D conversation is triggered after a short wait.
ii) Port B Configuration
Because PortB is used for 7-segment LED display, both TRISB and PORTB registers are cleared to display nothing at the beginning.
iii) Frequency Setting
The internal clock is set to 4MHZ, which is specified in the assignment guideline. This is implemented by setting the OSCCON register to b’01101110’.
iv) Interrupt Setting
This project uses 3 interrupts, A/D, TMR0 and TMR1. A/D is used for A/D conversations, TMR1 for a 33HZ signal generator, and TMR0 for pulses. INTCON and PIE1 are configured to enable these interrupts, and T1CON and OPTION_REG are used to scale TMR0 to 1:16, and TMR1 to 1:1. TMR1L and TMR1H are initialized so that the first TMR1 overflow interrupt will occur 1/33 second later, and the timers are started when the configurations are done.
b) Interrupt handler modules
After necessary tasks of the interrupt handler are done, the flags bits of interrupts will be checked. If a flag bit of an interrupt is set, a corresponding handle routine will be called. Routinely interrupt handler tasks will be performed at last.
i) TMR1 Interrupt
Both the initialization and the handler routine set TMR1H and TMR1L to 35233 to ensure the overflow interrupt will occur after 30303 cycles, or 1/33 seconds, thus generate a 33HZ clock. For convenience, a high pulse signal output for the Servomotor and an A/D conversation request is also placed here. In other words, the pulse is set to high every 1/33 seconds, and the A/D conversation is also triggered every 1/33 seconds. The TMR0 timer is also enabled to set the pulse to low after a period of time. This period is calculated after the voltage is read.
ii) A/D Interrupt
This interrupt handler does the heaviest job in the program. First, it copy the digitalized voltage into user defined variable named AnalogResultH and AnalogResultL, and AnalogResultL is abandoned since a continuum specified by AnalogResultH is enough. Then the duration of the high stage of the output pulse and the LAD output will be calculated. According to the document of the Servo, a high stage of 0.36ms will cause the Servo turn to left, and 2.3 ms will cause it to turn right. Suppose the A/D result 0 means left, and 255 means right, then the duration of the high stage can be calculated by the following formula: Duration = 0.36+AnalogResultH/256 * 1.94 ms = 360+AnalogResultH*1,940/256 cycles to store the duration in TMR0, we need to prescale it to fit. The upper bound of it is 2.3 ms, or 2,300 cycles. To make the maximum duration fit into a byte, the timer need to be prescaled to 1:16. Duration =360/16+(AnalogResultH/256) *(1,940/16) ticks =22.5+ AnalogResultH/256* 121.25 ticks Of course I can not do it with such precision with the little instruction set of the chip. Round downs are inevitable Duration ≈22 + AnalogResultH/256*121 ≈22 + -AnalogResultH/64 -AnalogResultH/128 -AnalogResultH/256 So, to make the TMR0 overflows Duration ticks after the TMR1 interrupt rise the pulse signal, the TMR0 register must be set to TMR0 =256- Duration. This result is stored in a variable named Time0Interval, and is used by the TMR1 interrupt handler routine. This routine also scales the analog result to one digit value and displays it on a 7-segment LED. It is done by getting the high 4 bits of the high byte of the analog result.
iii) TMR0 Interrupt
This interrupt handler routine merely turn the TMR0 interrupt off, and output a low signal to end a pulse. ** **
5) Overview of testing done before burning the chip
The test is done in the emulator. After loading the program into emulator, and execute it, it reads the value set on RA0, and output a pulse every 1/33HZ.
Microchip PIC16F88A Emulator Project
- 11 July 2005
Resources:
document
PIC16F88 resource center
USB driver in order to communicate with the board http://www.ftdichip.com/Drivers/FT232-FT245Drivers.htm#VCP
driving guide of the servo from a robotics project that used the Motorola 68HC11 microcontroller http://www.austincc.edu/rblack/COSC2425/Lectures/Day27/servo.pdf
Lab5 Step4
- 24 June 2005
END;
all: $(PROJECT).exe
Lab5 Draft3
- 23 June 2005
reference: http://homepages.ius.edu/jfdoyle/c335/Html/ProcInvoke.htm
all: $(PROJECT).exe
Lab5 Draft2
- 21 June 2005
;=====================================================================
; lab5.asm - build a program that displays the Fibonacci numbers for a user defined input upper bound
; Author: Sheng_Jiang
; Course: COSC 2425
; Date: 6/21/05
;=====================================================================
.386
.MODEL flat, stdcall
option casemap:none
include windows.inc ; always first
include macros.asm ; MASM support macros
; —————————————————————–
; include files that have MASM format prototypes for function calls
; —————————————————————–
include masm32.inc
include gdi32.inc
include user32.inc
include kernel32.inc
; ————————————————
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ————————————————
includelib masm32.lib
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
;costants
CR EQU 0Dh
LF EQU 0Ah
TABLEWIDTH EQU 10
HBAR EQU 196
VBAR EQU 179
ULCORNER EQU 218
URCORNER EQU 191
MLBORDER EQU 195
MRBORDER EQU 180
LLCORNER EQU 192
LRCORNER EQU 217
.Data
menuSelection BYTE 0
menustring BYTE “Menu|I - Display program instructions|N - The user is to enter an integer number from 0 to 20|Display the first N Fibonacci numbers on the console|Quit the program”
menustringLen DWORD $-menustring
menuDelimiter DWORD “|”
IsExitSelected BYTE 0
number BYTE 0
.CODE
;print a string
;usage: push stringBuffer
; push stringlen
;
;call OutputStringN
; pop stringlen
; pop stringBuffer
OutputStringN PROC
push ebp
mov ebp , esp
sub esp , 8 ;//2 local var
push eax
push ecx
push edx
;eax=GetStdHandle(STD_OUTPUT_HANDLE)
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov [ebp-4] , eax ;
;[ebp-8]=ebp-8;
mov eax ,ebp
sub eax ,8
mov [ebp-8] , eax;
;WriteFile outputHandle, stringBuffer,stringlen,&bytesWritten,0
invoke WriteFile, [ebp-4], near ptr [ebp+12], [ebp+8], near ptr [ebp-8],0
;cleanup
pop edx
pop ecx
pop eax
add esp , 8
mov esp,ebp
pop ebp
ret
OutputStringN ENDP
;print a char for count times.
;usage: push char
; push count
; call OutputCharN
; pop count
; pop char
OutputCharN PROC
push ebp
mov ebp , esp
push eax
push ecx
push edi
mov ecx,[ebp+8] ;ecx=count
JCXZ OutputCharNCleanup; do nothing if count=0
;allocate count bytes on the stack
;from esp-count to esp
;and initialize to char
;BYTE buffer[count]
;edi=buffer;
;push ecx;
;while(ecx)
;{
; edi[ecx]=char
;}
;pop ecx
mov al,BYTE PTR [ebp+12]
mov edi,esp
sub esp,ecx
push ecx
OutputCharNLoop:
dec edi
mov [edi], al
loop OutputCharNLoop
pop ecx
;call OutputStringN(buffer,ecx)
push edi
push ecx
call OutputStringN
pop ecx
add esp,4
;free count bytes on the stack
add esp,ecx
OutputCharNCleanup:
pop edi
pop ecx
pop eax
mov esp,ebp
pop ebp
ret
OutputCharN ENDP
;print a char
;by calling OutputStringN with a count of 1
;usage: push char
; call OutputChar
; pop char
OutputChar PROC
push ebp
mov ebp , esp
push eax
;DWORD dwchar;
sub esp,4
mov eax,[ebp+8] ;eax=char
mov dword ptr[ebp-8],0 ;dwchar=0
mov byte ptr[ebp-8],al ;dwchar=char & 0x000000FF
;call OutputStringN(&dwchar,1)
mov eax,ebp
sub eax,8
push eax
push 1
call OutputStringN
add esp,12
pop eax
mov esp,ebp
pop ebp
ret
OutputChar ENDP
;draw a table line with text and delimiters
;usage:
;push TableWidth
;push beginChar
;push textbuffer
;push textlen
;push fillchar
;push endChar
;call DrawTableLine
;pop endChar
;pop fillchar
;pop textlen
;pop textbuffer
;pop beginChar
;pop TableWidth
DrawTableLine PROC
push ebp
mov ebp , esp
push eax
push ebx
push ecx
; do nothing if TableWidth<2
mov ecx,[ebp+28] ;ecx=TableWidth
cmp ecx,2
jb DrawTableLineCleanup
;beginChar, the left border
push [ebp+24]
call OutputChar
add esp,4
;the text
;ebx=min(TableWidth-2,textlen);
mov ebx,[ebp+16] ;ebx=textlen
mov eax,ebx
add eax,2 ;eax=textlen+2
cmp eax,ecx ;textlen+2<=TableWidth?
jbe DrawTableLinePrintText ;yes, print it
mov ebx,ecx ;otherwise cut the string to TableWidth-2 characters
sub ebx,2 ;ebx=TableWidth-2
DrawTableLinePrintText:
;if no text to print,jump to fill the whole line
cmp ebx,0
je DrawTableLineFillLine
; call OutputStringN to print the text part
push [ebp+20]
push ebx
call OutputStringN
pop ebx
add esp,4
DrawTableLineFillLine:
;fill the rest of table line
;call OutputCharN(fillchar,TableWidth-2-ebx)
mov eax, [ebp+28]
sub eax, 2
sub eax, ebx
push [ebp+12]
push eax
call OutputCharN;
add esp,8
;endChar, the right border
push [ebp+8]
call OutputChar
add esp,4
;change line
push CR
call OutputChar
add esp,4
push LF
call OutputChar
add esp,4
DrawTableLineCleanup:
pop ecx
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DrawTableLine ENDP
;draw a table top line(using ASCII code)
;usage:
;push TableWidth
;call DrawTableTop
;pop TableWidth
DrawTableTop PROC
push ebp
mov ebp , esp
;call DrawTableLine(TableWidth,ULCORNER,NULL,NULL,HBAR,URCORNER)
push [esp+8];TableWidth
push ULCORNER
push 0;
push 0;
push HBAR
push URCORNER
call DrawTableLine
add esp,24
mov esp,ebp
pop ebp
ret
DrawTableTop ENDP
;draw a table buttom line(using ASCII code)
;usage:
;push TableWidth
;call DrawTableButtom
;pop TableWidth
DrawTableButtom PROC
push ebp
mov ebp , esp
;call DrawTableLine(TableWidth,LLCORNER,NULL,NULL,HBAR,LRCORNER)
push [esp+8];TableWidth
push LLCORNER
push 0;
push 0;
push HBAR
push LRCORNER
call DrawTableLine
add esp,24
mov esp,ebp
pop ebp
ret
DrawTableButtom ENDP
;draw a table middle line(using ASCII code)
;usage:
;push TableWidth
;call DrawTableMiddleLine
;pop TableWidth
DrawTableMiddleLine PROC
push ebp
mov ebp , esp
;call DrawTableLine(TableWidth,MLBORDER,NULL,NULL,HBAR,MRBORDER)
push [esp+8];TableWidth
push MLBORDER
push 0;
push 0;
push HBAR
push MRBORDER
call DrawTableLine
add esp,24
mov esp,ebp
pop ebp
ret
DrawTableMiddleLine ENDP
;draw table lines and print text (using ASCII code)
;wrap to seperate lines if the text is too long, or delimiters were found in the text
;usage:
;push TableWidth
;push stringbuffer
;push stringlen
;push delimiter
;call DrawTableLineWithWrap
;pop delimiter
;pop stringlen
;pop stringbuffer
;pop TableWidth
DrawTableLineWithWrap PROC
push ebp
mov ebp , esp
push eax ;
push ebx ;
push ecx ;
push edx ;
push edi ;
push esi ;
mov ebx ,[ebp+8] ;delimiter
mov ecx ,[ebp+12] ;stringlen
mov edx ,[ebp+20] ;TableWidth
mov esi ,[ebp+16] ;stringbuffer
;DWORD curlinebase=esi;
;BOOL bTerminate=FALSE;
;BOOL bDelimiter;
;edi=esi;
;
;while(!bTerminate&&edi<esi+ecx)
;{
; if(edi==esi+ecx-1 /*end of buffer*/){bDelimiter=FALSE;bTerminate=TRUE;}
; else if([edi]==’’){bDelimiter=TRUE;bTerminate=TRUE;}
; else if([edi]==ebx /*delimiter*/{bDelimiter=TRUE;}
; else if(edi=curlinebase+TableWidth-2) /*wrap*/{bDelimiter=FALSE;}
; else {edi++; continue;}
; DrawTableLine(TableWidth,MLBORDER,curlinebase,bDelimiter?edi-curlinebase:edi-curlinebase+1,HBAR,MRBORDER);
; edi++;
; curlinebase=edi;
;}
mov edi ,esi
;allocate local vars
sub esp ,12
;DWORD& curlinebase=*(ebp-36);6 pushed registers
;BOOL& bTerminate=*(ebp-32)
;BOOL& bDelimiter=*(ebp-28)
mov dword ptr [ebp-36],esi
mov dword ptr [ebp-32],0
DrawTableLineWithWrapLoop:
;if(bTerminate==TRUE) goto DrawTableLineWithWrapCleanup
cmp dword ptr [ebp-32],0
jne DrawTableLineWithWrapCleanup
;if(edi>=esi+ecx) goto DrawTableLineWithWrapCleanup
mov eax,esi
add eax,ecx
cmp edi,eax
jae DrawTableLineWithWrapCleanup
dec eax
;if(edi==esi+ecx-1) goto DrawTableLineWithWrapEndOfBuffer
cmp edi,eax
je DrawTableLineWithWrapEndOfBuffer
;if([edi]==0) goto DrawTableLineWithWrapNullTerminator
cmp byte ptr [edi],0
je DrawTableLineWithWrapNullTerminator
;if([edi]==ebx) goto DrawTableLineWithWrapDelimiter
cmp byte ptr [edi],bl
je DrawTableLineWithWrapDelimiter
;if(edi==curlinebase+TableWidth-2) goto DrawTableLineWithWrapLineWrap
mov eax,[ebp-36]
add eax,edx
sub eax,2
cmp edi,eax
je DrawTableLineWithWrapLineWrap
inc edi
jmp DrawTableLineWithWrapLoop
DrawTableLineWithWrapEndOfBuffer:
;bTerminate=TRUE,bDelimiter=FALSE;
mov dword ptr [ebp-32],1
mov dword ptr [ebp-28],0
jmp DrawTableLineWithWrapDrawLine
DrawTableLineWithWrapNullTerminator:
;bTerminate=TRUE,bDelimiter=TRUE;
mov dword ptr [ebp-32],1
mov dword ptr [ebp-28],1
jmp DrawTableLineWithWrapDrawLine
DrawTableLineWithWrapDelimiter:
;bDelimiter=TRUE;
mov dword ptr [ebp-28],1
jmp DrawTableLineWithWrapDrawLine
DrawTableLineWithWrapLineWrap:
;bDelimiter=FALSE;
mov dword ptr [ebp-28],0
;jmp DrawTableLineWithWrapDrawLine
DrawTableLineWithWrapDrawLine:
; DrawTableLine(TableWidth,MLBORDER,curlinebase,bDelimiter?edi-curlinebase:edi-curlinebase+1,HBAR,MRBORDER);
push edx ;TableWidth
push MLBORDER ;beginchar
push [ebp-36] ;stringbuffer
;eax=bDelimiter?edi-curlinebase:edi-curlinebase+1
mov eax,edi
sub eax,[ebp-36]
cmp dword ptr [ebp-28],0
jne DrawTableLineWithWrapDrawLine2
add eax,1
DrawTableLineWithWrapDrawLine2:
push eax ;bufferlen
push HBAR ;fillchar
push MRBORDER ;endchar
call DrawTableLine
add esp,24
; edi++;
; curlinebase=edi;
inc edi
mov [ebp-36],edi
jmp DrawTableLineWithWrapLoop
DrawTableLineWithWrapCleanup:
add esp ,12
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DrawTableLineWithWrap ENDP
ShowMenu Proc
push ebp
mov ebp , esp
push TABLEWIDTH
call DrawTableTop
;add esp,4
;push TABLEWIDTH
push OFFSET menustring
push menustringLen
push menuDelimiter
call DrawTableLineWithWrap
sub esp,12
;push TABLEWIDTH
call DrawTableButtom
add esp,4
mov esp,ebp
pop ebp
ret
ShowMenu EndP
;invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
main PROC
int 3
; call ShowMenu
;text code of OutputChar
; push VBAR
; call OutputChar
; add esp,4
;test code of DrawTableLineWithWrap
push TABLEWIDTH
push OFFSET menustring
push menustringLen
push menuDelimiter
call DrawTableLineWithWrap
sub esp,12
exit
main ENDP
END main
#=====================================================================
# lab5 - build a program that displays the Fibonacci numbers for a user defined input upper bound
# Author: Sheng_Jiang
# Course: COSC 2425
# Date: 6/21/05
#=====================================================================
PROJECT = Lab5
NAME = Sheng_Jiang
Date = 6/21/05
ROOTDRIVE = C
VERSION = V1
SRCS =
$(PROJECT).asm
makefile
MASM32 = $(ROOTDRIVE):/masm32
ML = $(MASM32)/bin/ml
LINK = $(MASM32)/bin/link
Zip = H:/mydoc/Tools/Bin/zip
DEBUG = c:/masm32/debug/windbg
MLFLAGS = /I. /I $(MASM32)include /I $(MASM32)macros /Zi /Zd /Zf /c /Fl /coff /Cp
LINKFLAGS = /subsystem:console /libpath:$(MASM32)lib /debug
DEBUGFLAGS = -QY -g -G -WF $(PROJECT).WEW
all: $(PROJECT).exe
$(PROJECT).obj: $(PROJECT).asm
$(ML) $(MLFLAGS) $(PROJECT).asm
$(PROJECT).exe: $(PROJECT).obj
$(LINK) $(LINKFLAGS) $(PROJECT).obj
clean:
del $(PROJECT).exe *.obj *.lst *.map *.pdb *.ilk
zip: clean
del $(NAME)_$(PROJECT)_$(VERSION).zip
$(Zip) $(NAME)_$(PROJECT)_$(VERSION).zip $(SRCS)
debug: $(PROJECT).exe
$(DEBUG) $(DEBUGFLAGS) $(PROJECT).exe
Lab5 Draft1
- 20 June 2005
;=====================================================================
; lab5.asm - build a program that displays the Fibonacci numbers for a user defined input upper bound
; Author: Sheng_Jiang
; Course: COSC 2425
; Date: 6/15/05
;=====================================================================
.386
.MODEL flat, stdcall
option casemap:none
include windows.inc ; always first
include macros.asm ; MASM support macros
; —————————————————————–
; include files that have MASM format prototypes for function calls
; —————————————————————–
include masm32.inc
include gdi32.inc
include user32.inc
include kernel32.inc
; ————————————————
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ————————————————
includelib masm32.lib
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
;costants
CR EQU 0Dh
LF EQU 0Ah
DOCOMMAND_CONTINUE equ 1
DOCOMMAND_END equ 0
.Data
menuSelection DWORD 0
DoCommandResult DWORD 0
.Code
ShowMenu Proc
print chr$(“Menu”,CR,LF,”[I,N,F,X]”)
ret
ShowMenu EndP
;
;usage:
;push someThingToAllocateTheReturnValue
;push command
;call DoCommand
;pop command
;pop someThingToAllocateTheReturnValue
;the return value can be one of the following:
; DOCOMMAND_CONTINUE equ 1
; DOCOMMAND_END equ 0
DoCommand PROC
push ebp
mov ebp, esp
push eax
push ebx
mov bl, BYTE PTR [ebp+8]
cmp bl, ‘x’
je DoCommandEnd
cmp bl, ‘X’
je DoCommandEnd
mov eax, DOCOMMAND_CONTINUE
jmp DoCommandCleanup
DoCommandEnd:
mov eax, DOCOMMAND_END
DoCommandCleanup:
mov [ebp+12],eax
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DoCommand ENDP
main PROC
int 3
cls
ShowMenuLoop:
call ShowMenu
mov menuSelection, input()
push DoCommandResult
mov eax,menuSelection
push [eax]
call DoCommand
pop menuSelection
pop DoCommandResult
cmp DoCommandResult,DOCOMMAND_CONTINUE
je ShowMenuLoop
exit
main ENDP
END main
#=====================================================================
# lab5 - build a program that displays the Fibonacci numbers for a user defined input upper bound
# Author: Sheng_Jiang
# Course: COSC 2425
# Date: 6/15/05
#=====================================================================
PROJECT = Lab5
NAME = Sheng_Jiang
Date = 6/15/05
ROOTDRIVE = C
VERSION = V1
SRCS =
$(PROJECT).asm
makefile
MASM32 = $(ROOTDRIVE):/masm32
ML = $(MASM32)/bin/ml
LINK = $(MASM32)/bin/link
Zip = H:/mydoc/Tools/Bin/zip
DEBUG = c:/masm32/debug/windbg
MLFLAGS = /I. /I $(MASM32)include /I $(MASM32)macros /Zi /Zd /Zf /c /Fl /coff /Cp
LINKFLAGS = /subsystem:console /libpath:$(MASM32)lib /debug
DEBUGFLAGS = -QY -g -G -WF $(PROJECT).WEW
all: $(PROJECT).exe
$(PROJECT).obj: $(PROJECT).asm
$(ML) $(MLFLAGS) $(PROJECT).asm
$(PROJECT).exe: $(PROJECT).obj
$(LINK) $(LINKFLAGS) $(PROJECT).obj
clean:
del $(PROJECT).exe *.obj *.lst *.map *.pdb *.ilk
zip: clean
del $(NAME)_$(PROJECT)_$(VERSION).zip
$(Zip) $(NAME)_$(PROJECT)_$(VERSION).zip $(SRCS)
debug: $(PROJECT).exe
$(DEBUG) $(DEBUGFLAGS) $(PROJECT).exe
Lab4
- 13 June 2005
;=====================================================================
; lab4.asm - Example function call to get the 20th Fibonacci number
;; Author: Sheng_Jiang
; Course: COSC 2425
; Date: 6/13/05;=====================================================================
.386
.MODEL flat, stdcall
option casemap:none
include windows.inc ; always first
include macros.asm ; MASM support macros
; —————————————————————–
; include files that have MASM format prototypes for function calls
; —————————————————————–
include masm32.inc
include gdi32.inc
include user32.inc
include kernel32.inc
; ————————————————
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ————————————————
includelib masm32.lib
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
;costants
cr equ 0dh
lf equ 0ah
.Data
.STACK 4096h ;RECURSION need large stacks
.CODE
;Function Fibonacci returns n’th Fibonacci number
;It uses RECURSION
;__stdcall unsigned int f(int x)
;{
; return (x<2) ? 1 : f(x-1) + f(x-2);
;}
;usage:
;push SomethingToAllocateTheReturnValue
;push Parameter;
;call Fibonacci
;stack changes during function call:12
Fibonacci PROC
push ebp
mov ebp , esp
push ecx ; this register is used to calculate the parameters of the function calls
push esi ; sum goes here
FibonacciFunctionBegin:
mov ecx,[ebp+8] ;ecx=param1 = esp/*old*/+4/*new esp*/+4/*pushed ebp*/
cmp ecx,2 ;ecx<2 ?
jge FibonacciRecursion ;return f(x-1) + f(x-2);
mov esi,1 ;otherwise return 1
jmp FibonacciCleanup ;exit function
FibonacciRecursion:
dec ecx ;calculate f(x-1)
push ecx ;allocate the returnValue
push ecx ;ecx=x-1
call Fibonacci
pop esi
dec ecx ;calculate f(x-2)
push ecx ;allocate the returnValue
push ecx ;ecx=x-2
call Fibonacci
pop ecx
add esi,ecx
FibonacciCleanup:
mov dword ptr [ebp+12],esi; //set return values
pop esi
pop ecx
mov esp,ebp
pop ebp
ret 4
Fibonacci ENDP
;int main(int argc, char* argv[])
;{
; printf(“the 20th Fibonacci number is:rn”;
; return 0;
;}
main PROC
int 3
push ecx ;allocate the return value
push 13 ;
call Fibonacci
print chr$(“the 20th Fibonacci number is:”,cr,lf)
pop ecx
print str$(ecx);
print chr$(cr,lf)
exit
main ENDP
END main
# makefile for Lab4
PROJECT = Lab4
NAME = Sheng_Jiang
Date = 6/13/05
ROOTDRIVE = C
VERSION = V1
SRCS =
$(PROJECT).asm
makefile
MASM32 = $(ROOTDRIVE):/masm32
ML = $(MASM32)/bin/ml
LINK = $(MASM32)/bin/link
Zip = H:/mydoc/Tools/Bin/zip
DEBUG = c:/masm32/debug/windbg
MLFLAGS = /I. /I $(MASM32)include /I $(MASM32)macros /Zi /Zd /Zf /c /Fl /coff /Cp
LINKFLAGS = /subsystem:console /libpath:$(MASM32)lib /debug
DEBUGFLAGS = -QY -g -G -WF $(PROJECT).WEW
all: $(PROJECT).exe
$(PROJECT).obj: $(PROJECT).asm
$(ML) $(MLFLAGS) $(PROJECT).asm
$(PROJECT).exe: $(PROJECT).obj
$(LINK) $(LINKFLAGS) $(PROJECT).obj
clean:
del $(PROJECT).exe *.obj *.lst *.map *.pdb *.ilk
zip: clean
del $(NAME)_$(PROJECT)_$(VERSION).zip
$(Zip) $(NAME)_$(PROJECT)_$(VERSION).zip $(SRCS)
debug: $(PROJECT).exe
$(DEBUG) $(DEBUGFLAGS) $(PROJECT).exe
Lab3
- 01 June 2005
.386
.MODEL flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include masm32.inc
includelib kernel32.lib
includelib masm32.lib
.DATA
val1 DWORD 10000h
val2 DWORD 40000h
val3 DWORD 20000h
finalVal DWORD ?
.CODE
main PROC
int 3
mov eax,val1
add eax,val2
sub eax,val3
mov finalVal,eax
invoke ExitProcess, 0
main ENDP
END main
# makefile for Lab3
PROJECT = Lab3
NAME = Sheng_Jiang
Date = 5/25/05
ROOTDRIVE = C
VERSION = V1
SRCS =
$(PROJECT).asm
makefile
MASM32 = $(ROOTDRIVE):/masm32
ML = $(MASM32)/bin/ml
LINK = $(MASM32)/bin/link
Zip = H:/mydoc/Tools/Bin/zip
DEBUG = H:Progra~1Debugg~1windbg
MLFLAGS = /I. /I $(MASM32)include /Zi /Zd /Zf /c /Fl /coff /Cp
LINKFLAGS = /subsystem:console /libpath:$(MASM32)lib /debug
DEBUGFLAGS = -QY -g -G -WF $(PROJECT).WEW
all: $(PROJECT).exe
$(PROJECT).obj: $(PROJECT).asm
$(ML) $(MLFLAGS) $(PROJECT).asm
$(PROJECT).exe: $(PROJECT).obj
$(LINK) $(LINKFLAGS) $(PROJECT).obj
clean:
del $(PROJECT).exe *.obj *.lst *.map *.pdb *.ilk
zip: clean
del $(NAME)_$(PROJECT)_$(VERSION).zip
$(Zip) $(NAME)_$(PROJECT)_$(VERSION).zip $(SRCS)
debug: $(PROJECT).exe
$(DEBUG) $(DEBUGFLAGS) $(PROJECT).exe
Attending Machine Language Class
- 23 May 2005
I am going to take the machine language class at ACC. a lot of posts are going to focus on my experience.
https://web.archive.org/web/20041110185729/https://www.austincc.edu/rblack/COSC2425/index.html