cat test01.cpp
#include <cstdio>
#include <cstring>
// C4514 unreferenced inline function has been removed
#pragma warning(disable : 4514)
extern "C" unsigned int __stdcall TestProc(unsigned int dwValue);
extern "C" unsigned int __stdcall MoveProc(char * buf);
extern "C" unsigned int __stdcall ParamProc(int x, short y, char z);
extern "C" unsigned int __stdcall PushPopProc(void);
extern "C" unsigned int __stdcall PPesiedi(void);
extern "C" unsigned int __stdcall LoopTest1(void);
extern "C" unsigned int __stdcall IncDecTest(void);
extern "C" unsigned int __stdcall AddSubTest(int x, int y);
extern "C" unsigned int __stdcall MulDivTest(int x, short y);
extern "C" unsigned int __stdcall LogicalFunction(void);
extern "C" unsigned int __stdcall ShiftFunction(void);
extern "C" unsigned int __stdcall CmpFunction(void);
extern "C" unsigned int __stdcall LoopFunction(void);
extern "C" unsigned int __stdcall IfMacroTest(void);
extern "C" unsigned int __stdcall RepeatMacroTest(void);
extern "C" unsigned int __stdcall InvokeTest(void);
extern "C" unsigned int __stdcall LocalMemTest(void);
int main(int argc, char ** argv)
{
unsigned int dwValue = 100;
unsigned int dwReturn = TestProc(dwValue);
printf("%d\n", dwReturn);
printf(">");
getchar();
char buf[100];
strcpy_s(buf,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\0");
MoveProc(buf);
printf("%s\n",buf);
ParamProc(10,2,1);
PushPopProc();
PPesiedi();
LoopTest1();
IncDecTest();
dwReturn = AddSubTest(2,3);
printf("2+2-3=%d\n", dwReturn);
dwReturn=MulDivTest(10,3);
printf("10*10/3=%d\n", dwReturn);
LogicalFunction();
ShiftFunction();
CmpFunction();
LoopFunction();
IfMacroTest();
RepeatMacroTest();
dwReturn=InvokeTest();
printf("100+100=%d\n", dwReturn);
LocalMemTest();
return 0;
}
cat test.asm
.486
.model flat, stdcall
option casemap :none
.code
TestProc proc dwValue:DWORD
mov eax, dwValue
add eax, 100
ret
TestProc endp
MoveProc proc buf_ptr:DWORD
mov eax, 100
mov al, bl ; move the lower byte of ebx into the lower byte of eax
mov al, 0ffh ; move 0xFF into the lower byte of eax
mov ah, 0ffh ; move 0xFF into the high byte of the low word (2-bytes) of eax
mov ax, 0ffffh ; move 0xFFFF into the low word of eax
mov eax, 0ffffh ; move 0xFFFF into eax
mov eax,buf_ptr
push esi
push edi
mov esi,eax
mov edi,eax
mov al, [esi] ; move the byte contained in the memory address
; in register esi into the lower byte of eax
mov bl,al
inc al
mov bl,al
mov [edi], bl ; move the byte value in the lowest byte of ebx
; into the memory address in register edi
inc esi
inc edi
mov cx, [esi] ; move the word (2-byte) value contained in the
; memory address of register esi into the lower word of ecx
add cx,0101h
mov edx,44444444h
mov dx,cx
mov [edi], edx ; move the dword (4-byte) value contained in edx
; into the memory address contained in register edi
mov al, [esi + 3] ; move the byte contained in the memory address
; in register esi + 3 into the lower byte of eax
add dx,0101h
mov [edi + 2], dx ; move the lower word (2-bytes) contained in
; edx into the memory address contained in the
; register edi + 2
pop edi
pop esi
ret
MoveProc endp
ParamProc proc dwValue1:DWORD, wValue2:WORD, bValue3:BYTE
ret
ParamProc endp
PushPopProc proc
mov eax, 100
push eax ; Stack now contains { 100 }
mov eax, 200
push eax ; Stack now contains { 200, 100 }
mov eax, 300
push eax ; Stack now contains ( 300, 200, 100 }
pop eax ; eax = 300, stack = { 200, 100 }
pop eax ; eax = 200, stack = { 100 }
pop eax ; eax = 100, stack = { }
ret
PushPopProc endp
PPesiedi proc
push ebx
push esi
push edi
; code goes in here
pop edi
pop esi
pop ebx
ret
PPesiedi endp
LoopTest1 proc
xor eax, eax ; efficient way of saying eax = 0
mov ecx, 5 ; ecx is the register generally used for counters
LoopStart: ; this is a label, used for labelling code positions
inc eax
dec ecx
jnz LoopStart
; eax now equals 5
ret
LoopTest1 endp
IncDecTest proc
mov ecx, 10
xor eax, eax ; efficient way of saying eax=0
LoopStart:
inc eax
dec ecx
jnz LoopStart
; eax now equals 10
ret
IncDecTest endp
AddSubTest proc dwValue1:DWORD, dwValue2:DWORD
mov eax, dwValue1
add eax, dwValue1
sub eax, dwValue2
ret
AddSubTest endp
MulDivTest proc dwValue1:DWORD, wValue2:WORD
mov eax, 10
xor edx, edx ; set edx to zero
mul dwValue1
div wValue2
ret
MulDivTest endp
LogicalFunction proc
xor eax, eax ; the efficient way of saying eax=0
mov ax, 100
mov bx, 5
and ax, 1
or ax, bx
ret
LogicalFunction endp
ShiftFunction proc
mov eax, 1
shl eax, 2 ; shift eaxs bits left 2 times : i.e. eax *= 4
shr eax, 2 ; shift eaxs bits right 2 times : i.e. eax /= 4
ret
ShiftFunction endp
CmpFunction proc
mov eax, 100
cmp eax, 100
; jump if equals
je Equals
; not equal
mov eax, 2
jmp lbl1
Equals:
mov eax, 1
lbl1:
ret
CmpFunction endp
LoopFunction proc
xor eax, eax
mov ecx, 10
LoopStart:
inc eax
loop LoopStart
ret
LoopFunction endp
IfMacroTest proc
mov eax, 100
mov ecx, 200
.if eax == ecx
; do something
.else
; do something else
.endif
ret
IfMacroTest endp
RepeatMacroTest proc
xor eax, eax
mov ecx, 100
.repeat
inc eax
.untilcxz
mov al,3
.repeat
dec al
.until zero? ; if zero flag set
xor eax, eax
mov ecx, 100
.repeat
push ecx
mov ecx, 100
.repeat
inc eax
.untilcxz
pop ecx
.untilcxz
ret
RepeatMacroTest endp
Function1 proc dwValue:DWORD
add eax, 100
ret
Function1 endp
InvokeTest proc
mov eax, 100
invoke Function1, eax
; eax now = 200, i.e. eax += 100
ret
InvokeTest endp
LocalMemTest proc
LOCAL dwValue:DWORD ; allocates 4 bytes and labels it dwValue
LOCAL wValue:WORD ; allocates 2 bytes and labels it wValue
LOCAL bValue:BYTE ; allocates 1 byte and labels it bValue
xor eax, eax
mov dwValue, eax
mov wValue, ax
mov bValue, al
ret
LocalMemTest endp
end
cat makefile
.SUFFIXES: .exe .obj .asm
.PHONY: all clean mmm test
TARGET=test01
all: $(TARGET).exe
OBJS=$(TARGET).obj test.obj
$(TARGET).exe: $(OBJS)
link $^
@echo
$(TARGET).obj: $(TARGET).cpp
test.obj: test.asm
.cpp.obj:
cl -c -Wall -Od $<
@echo
.asm.obj:
ml -c -coff -Fo$@ $<
@echo
test: $(TARGET).exe
./$(TARGET).exe
clean:
@-rm $(TARGET).exe *.obj *~ 1>/dev/null 2>&1
mmm:
cat $(TARGET).cpp
@echo
cat test.asm
@echo
cat makefile
html:
cat /dev/clipboard | code2html.exe | unix2dos
|