【问题标题】:What's the difference between 'push' and 'pushq' in at&t assemblyat&t 汇编中的“push”和“pushq”有什么区别
【发布时间】:2018-06-23 10:12:16
【问题描述】:

我最近开始寻求更深入地了解我的计算机的工作原理。我的问题是关于 push 和 pushq 之间的区别。

我知道 push 会将一个值写入堆栈,我的假设是 pushq 做了类似的事情。 q 的存在让我认为应该有细微的差别,但我似乎无法理解其中的差别。

我说过在使用 gdb 和命令 'layout asm' 调试文件 /lib/udev/iphone-set-info 时要考虑这个问题。

有问题的代码是:

pushq  $0x0
push   %r9

我知道 $0x0 是 NULL 的十六进制,而 %r9 是通用寄存器之一。这是否只是意味着我们将 Null 写入堆栈,并在其上方写入寄存器 %r9?

【问题讨论】:

  • 没有区别,q 后缀是可选的,因为它是 64 位代码中的默认操作数大小。由于堆栈向下增长,零字节实际上在内存中高于%r9

标签: linux assembly gdb reverse-engineering att


【解决方案1】:

我不确定您使用的是哪种汇编语言,但对于也使用 AT&T 语法的 GAS(GNU 汇编程序)来说也是如此:GAS 汇编指令通常以字母“b”、“s”、“w”为后缀"、"l"、"q" 或 "t" 来确定正在操作的操作数的大小。

  • b = 字节(8 位)
  • s = 短(16 位整数)或单(32 位浮点)
  • w = 字(16 位)
  • l = long(32 位整数或 64 位浮点数)
  • q = 四边形(64 位)
  • t = 10 个字节(80 位浮点)

如果没有指定后缀,并且指令没有内存操作数,GAS 会根据目标寄存器操作数(最终操作数)的大小推断操作数大小。

pushq $0x0 只是将 8 个零字节压入堆栈。然后push %r9 定义%r9 是64 位寄存器并将其值压入堆栈。

关于堆栈的有趣事实是它会向下增长,因此空字节的地址将高于%r9 的值,所以这里可能会产生误解,因为实际上%r9 的值低于空字节。

【讨论】:

    猜你喜欢
    • 2018-03-22
    • 1970-01-01
    • 2015-09-04
    • 2019-02-25
    • 2012-03-10
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多