【问题标题】:asm64 write system call: non-adjacent memory?asm64写系统调用:非相邻内存?
【发布时间】:2015-04-28 11:01:27
【问题描述】:

我有这个用 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 个字节压入堆栈,当我调用缓冲区大小为 8 的写入时,我希望看到 EEEEAAAA,但输出为 EEEE。但是,当我将缓冲区大小 rdx 设置为 12 时,我可以看到完整的字符串 EEEEAAAA。那些四字节块之间是什么?他们不应该是相邻的吗?

【问题讨论】:

标签: assembly 64-bit


【解决方案1】:

每次推送写入 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

【讨论】:

  • 如@Aki Suihkonen 所说,将字符串作为 2 字节块推送也可以。
  • 推送 2 字节块效率低下,并且还会暂时弄乱堆栈对齐,这在某些情况下可能是一个问题。
猜你喜欢
  • 2021-03-20
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 2011-09-25
相关资源
最近更新 更多