asm64写入系统调用:非相邻内存?

时间:2015-04-28 11:01:28

标签: assembly 64-bit

我有这个用x64汇编编写的小程序:

xor    rdx,rdx
push   rdx            ;null terminator
push   0x41414141     ;AAAA
push   0x45454545     ;EEEE
mov    rsi,rsp        ;pointer to the string
mov    rdi,1          ;output file: stdout
mov    rdx,8          ;buffer size 8
mov    rax,1          ;write syscall
syscall

如您所见,我将八个字节压入堆栈,当我调用缓冲区大小为8的write时,我希望看到EEEEAAAA,但输出为EEEE。但是,当我将缓冲区大小rdx设置为12时,我可以看到完整的字符串EEEEAAAA。这些四字节块之间有什么关系?他们不应该相邻吗?

1 个答案:

答案 0 :(得分:2)

每次推送写入8个字节,因为这是64位模式下的堆栈大小。指令中的符号扩展为64位,请参阅指令集参考:如果源操作数的大小小于操作数大小,则会在堆栈上推送符号扩展值。

因此,您的堆栈看起来像(从rsp向上):

0x0000000045454545 ; EEEE sign extended to 64 bits
0x0000000041414141 ; AAAA sign extended to 64 bits
0x0000000000000000 ; NULL terminator

作为解决方法,您可以这样做:

xor rdx, rdx
push rdx
mov rax, 0x4141414145454545
push rax
mov    rsi,rsp        ;pointer to the string
mov    rdi,1          ;output file: stdout
mov    rdx,8          ;buffer size 8
mov    rax,1          ;write syscall
syscall