【发布时间】:2010-10-17 14:45:43
【问题描述】:
我正在将 NASM 源“移植”到 GAS,我发现以下代码行:
push byte 0
push byte 37
GAS 不允许“push byte”或“pushb”。
我应该如何将上面的代码翻译成 GAS 语法?
谢谢
【问题讨论】:
标签: assembly stack nasm gnu-assembler
我正在将 NASM 源“移植”到 GAS,我发现以下代码行:
push byte 0
push byte 37
GAS 不允许“push byte”或“pushb”。
我应该如何将上面的代码翻译成 GAS 语法?
谢谢
【问题讨论】:
标签: assembly stack nasm gnu-assembler
pushb 已从 GAS 中删除。您应该可以使用push 命令来获得相同的效果。更多信息是here。
【讨论】:
1) NASM 2.11 64 位中的 push byte 编译为与 push 相同,但如果推送的内容大于一个字节,它会拒绝编译:
push 0x0000
push 0x01
push 0x0001
push 0x10
等同于:
push byte 0x0000
push byte 0x01
push byte 0x0001
push byte 0x10
但以下失败:
push byte 0x0100
push byte 0x1000
push byte 0x01000000
push byte 0x10000000
所有这些都编译为指令的6a XX 形式。
2) NASM 和 GAS 会根据操作数大小自动决定使用哪种形式:
GAS 2.25:
push $0x0000
push $0x01
push $0x0001
push $0x10
push $0x0100
push $0x1000
push $0x01000000
push $0x10000000
编译为与 NASM 相同:
push 0x0000
push 0x01
push 0x0001
push 0x10
push 0x0100
push 0x1000
push 0x01000000
push 0x10000000
对象转储:
0: 6a 00 pushq $0x0
2: 6a 01 pushq $0x1
4: 6a 01 pushq $0x1
6: 6a 10 pushq $0x10
8: 68 00 01 00 00 pushq $0x100
d: 68 00 10 00 00 pushq $0x1000
12: 68 00 00 00 01 pushq $0x1000000
17: 68 00 00 00 10 pushq $0x10000000
因此,GAS 中的 push 与 NASM 中的 push byte 相同,但没有错误检查。
3) GAS中确实存在的修饰符是w,如:
pushw $0
编译为:
0: 66 6a 00 pushw $0x0
即,添加 0x66 前缀以切换 16 位操作。
NASM 的等价物是:
push word 0
4) 与mov 的区别在于我们无法控制任意推送大小:它们都是向堆栈推送固定数量。
我们可以控制指令编码的唯一参数是是否包含0x66前缀。
其余的由段描述符决定。请参阅Intel 64 and IA-32 Architectures Software Developer’s Manual - Volume 2 Instruction Set Reference - 325383-056US September 2015。
【讨论】: