masm 64位CPU汇编指令基础



extern MessageBoxA:proc
includelib user32.lib

NULL EQU 0
MB_OK EQU 0

.const
msg BYTE "Hello x64 world!",0    ;0 means msg end with '\0'
wintitle BYTE "App",0
.CODE
main PROC
mov rcx,NULL            ;arg1  hWnd
mov rdx,offset msg      ;arg2  lpText
mov r8,offset wintitle  ;arg3  lpCaption
mov r9d,MB_OK           ;arg4  uType
sub rsp,28h
;sub rsp,08h             ;8h  8 bytes for padding to 16 bytes alignment 
call MessageBoxA        ;push "xor" instruction addr for returning anchor
xor ecx,ecx             ;clear ecx
;add rsp,08h             ;restore rsp.
add rsp,28h
ret                     ;pop rip
main ENDP
END

;64位CPU规定,发起函数调用时,执行子函数第一条指令时栈顶地址需要对齐到16字节,而执行call指令时,会自动向栈中压入后一条指令的地址,8字节,如果在call之前,rsp已经是16的整数倍,则进入子函数后,rsp就因为偏移了8变得无法被16整除,所以需要人为地在call指令执行前对rsp偏移8字节,函数调用结束后,再人为地复位。
;在子函数内部,rcx, rdx, r8, r9 可能还有其他用处,此时一般会先将他们挪到栈上:mov [rsp+8],rcx  mov [rsp+10] rdx   mov [rsp+18] r8   mov [rsp+20] r9, 如果提前没有预留好空间,则会内存越界,发生崩溃(有的函数如果没有把rcx,rdx,r8,r9做其他用途,就不会崩溃)。因此惯例做法是在call之前额外预留20h的空间,call之后人为复位。
;综上,总是预先留足28h的空间。

; complie command: ml64.exe /Cp /c progx.asm
; link command: link.exe /MACHINE:x64 /ENTRY:main progx.obj

 参考资料https://it.cha138.com/android/show-58037.html

你可能感兴趣的:(汇编)