- 下面是一段可以执行的x64 的 nasm 汇编代码,类似可执行文件的外壳代码
bits 64
global start
extern MessageBoxA
section .text
start:
push rbp
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
jmp real_call
message: db 'hello',0
caption: db 'msg',0
real_call:
xor rcx,rcx
mov rdx,message
mov r8,caption
xor r9d,r9d
sub rsp,28h
call MessageBoxA
add rsp,28h
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rbp
ret
- 运行是崩溃的
- 这么简单的程序也会崩溃
- 没有什么逻辑啊???
看看出问题的是什么指令:
movaps xmmword ptr [rsp+150h],xmm8
提示:Access violation - code C0000005
查看栈rsp 并没有出问题
再查看一下 movaps 指令:
在网上查到这条指令说明:
从源操作数(第二个操作数)将包含四个压缩单精度浮点值的双四字移到目标操作数(第一个操作数)。此指令可用于将 128 位内存位置的内容加载到 XMM 寄存器、将 XMM 寄存器的内容存储到 128 位内存位置,或是在两个 XMM 寄存器之间移动数据。源操作数或目标操作数是内存操作数时,操作数必须对齐 16 字节边界,否则将生成一般保护性异常 (#GP)。
要在未对齐的内存位置中移入/移出压缩单精度浮点值,请使用 MOVUPS 指令。
再看rsp 的值是0x30f2e8
rsp+150h 的确是不被16整除
哪里引起的呢?
在保留寄存器的时候保留了15个寄存器,恰好不能被16 整除。所以出现了问题。
汇编写代码的时候要注意啊。