cat test03.cpp
#include <cstdio>
// C4514 unreferenced inline function has been removed
#pragma warning(disable : 4514)
void func() {
printf("function called\n");
}
int func2(int arg1, int arg2, int arg3) {
printf("arg1=%d, arg2=%d, arg3=%d\n", arg1, arg2, arg3);
return arg1 + arg2 + arg3;
}
int main() {
// jump
int value = 0;
__asm {
jmp label
add value, 100
label:
add value, 1000;
}
printf("value=%d\n", value);
char * tc = "value==100\n";
char * fc = "value!=100\n";
char * result;
printf("value:");
scanf_s("%d",&value);
__asm {
cmp value, 100
jz cmp_true ; jump if equal
mov ebx, fc;
mov result, ebx;
jmp end
cmp_true:
mov ebx, tc;
mov result, ebx;
end:
}
printf(result);
// conditional jumps
// JA above (CF = 0 & ZF = 0)
// JAE above or equal(CF = 0)
// JB below(CF = 1)
// JBE below or equal(CF = 1 | ZF = 1)
// JC if carry set (CF = 1)
// JCXZ if CX==0
// JE equal(ZF = 1)
// JG greater (ZF = 0 & SF = OF)
// JGE greater or equal(SD = OF)
// JL less(SF ! OF)
// JLE less or equal(ZF = 1 | SF ! OF)
// JNA not above(CF = 1 | ZF = 1)
// JNAE not above or equal(CF = 1)
// JNB not below(CF = 0)
// JNBE not below or equal(CF = 0 & ZF = 0)
// JNC if no carry set(CF = 0)
// JNE != (ZF = 0)
// JNG not greater (ZF = 1 | SF ! OF)
// JNGE not greater or equal (SF ! OF)
// JNL not less(SF = OF)
// JNLE not less or equal (ZF = 0 & SF = OF)
// JNO no overflow(OF = 0)
// JNP no parity(PF = 0)
// JNS no sign(SF = 0) (non negative)
// JNZ non zero(ZF = 0)
// JO overflow(PF = 1)
// JP parity(PF = 1)
// JPE even parity(PF = 1)
// JPO odd parity(PF = 0)
// JS sign(SF = 1) (negative)
// JZ zero(ZF = 1)
//
int a, b;
char * r1 = "a > b\n";
char * r2 = "a < b\n";
char * r3 = "a == b\n";
printf("a :");
scanf_s("%d", &a);
printf("b :");
scanf_s("%d", &b);
__asm {
mov eax, a;
cmp eax, b;
ja label1;
jb label2;
mov ebx, r3;
mov result, ebx;
jmp end2;
label1:
mov ebx, r1;
mov result, ebx;
jmp end2;
label2:
mov ebx, r2;
mov result, ebx;
end2:
}
printf(result);
// loop
char teststr[32];
char * p = teststr;
__asm {
mov al, 'A';
mov ecx, 26;
label3:
mov ebx, p;
mov [ebx], al;
inc p;
inc al;
cmp ecx, 0
dec ecx
ja label3
mov ebx, p;
mov [ebx], 0;
}
printf("%s\n", teststr);
p = teststr;
__asm {
mov al, 'a';
mov ecx, 26;
label4:
mov ebx, p;
mov [ebx], al;
inc p;
inc al;
loop label4;
mov ebx, p;
mov [ebx], 0;
}
printf("%s\n", teststr);
// call - ret
int rr1, rr2, rr3, rr4;
__asm {
jmp end3;
setZero:
mov eax, 0;
mov ebx, 0;
mov ecx, 0;
mov edx, 0;
ret;
setRegister:
mov rr1, eax;
mov rr2, ebx;
mov rr3, ecx;
mov rr4, edx;
ret;
end3:
}
__asm call setRegister
printf("EAX=%d, EBX=%d, ECX=%d, EDX=%d\n", rr1, rr2, rr3, rr4);
__asm {
call setZero
call setRegister
}
printf("EAX=%d, EBX=%d, ECX=%d, EDX=%d\n", rr1, rr2, rr3, rr4);
// recursive call
int c;
__asm call routine1;
printf("A=%d, B=%d, C=%d\n", a, b, c);
// push pop
int r, v;
__asm mov r, esp;
printf("ESP=%p\n", r);
__asm {
push 10;
mov r, esp;
}
printf("Push ESP=%p\n", r);
__asm {
push 20;
mov r, esp;
}
printf("Push ESP=%p\n", r);
__asm {
push 30;
mov r, esp;
}
printf("Push ESP=%p\n", r);
__asm {
pop v;
mov r, esp;
}
printf("Pop V=%d, ESP=%p\n", v, r);
__asm {
pop v;
mov r, esp;
}
printf("Pop V=%d, ESP=%p\n", v, r);
__asm {
pop v;
mov r, esp;
}
printf("Pop V=%d, ESP=%p\n", v, r);
// function call
__asm call func;
// function call with parameter and return value
__asm {
push 1000;
push 100;
push 10;
call func2;
pop ebx;
pop ebx;
pop ebx;
mov result, eax;
}
printf("result=%d\n", result);
return 0;
__asm {
routine1:
mov a, 10;
call routine2;
ret;
routine2:
mov b, 20;
call routine3;
ret;
routine3:
mov c, 30;
ret
}
}
cat makefile
.PHONY: all test mmm clean
.SUFFIXES: .exe .obj
TARGET=test03
all: $(TARGET).exe
LOPT=
OBJS=$(TARGET).obj
$(TARGET).obj: $(TARGET).cpp
$(TARGET).exe: $(OBJS)
link $^ /out:$@ $(LOPT)
.cpp.obj:
cl -c -Wall -Od $<
test: $(TARGET).exe
./$(TARGET).exe
clean:
@-rm $(TARGET).exe *.obj *~ 1>/dev/null 2>&1
mmm:
cat $(TARGET).cpp
@echo
cat makefile
html:
cat /dev/clipboard | code2html.exe | unix2dos
install: $(TARGET).exe
cp $(TARGET).exe ~/bin
|