关于字节模式622c24
,有两种情况。
第一种情况:objdump
-as
对。
objdump
将622c24
分解为: bound %ebp,(%esp)
as
将bound %ebp,(%esp)
汇编为:622c24
第二种情况:库Capstone
-keystone
对。
Capstone
将622c24
分解为: bound (%esp), %ebp
Keystone
将bound (%esp), %ebp
组合为:622c24
如上所示,源和目标的位置颠倒了。
bound %ebp,(%esp)
bound (%esp), %ebp
根据AT&T语法,BOUND r32, m32
是正确的。
因此,这意味着Capstone-keystone的消除是正确的。
问题。因此,objdump
-as
在拆卸bound
指令时有问题吗?
这是binutils的错误吗?
答案 0 :(得分:3)
是的,这可能是AT&T语法中的设计错误。它们通常遵循以下模式:从Intel语法反转操作数,并重命名符号/零扩展助记符(cdq
=> cltq
,movsx eax, byte[mem]
=> movsbl
。偏离可以视为设计错误。
但不是实现错误,除非旧版本不同。当AT&T随心所欲地为不同的指令制定自己的规则时,这是有效的(但不愉快)。这可能是与原始Unixware汇编程序兼容的另一种情况。 (请参见下文)。
The bound
instruction不会写任何一个输入操作数,所以两个都不是目的地。而且与cmp
不同,操作数顺序没有任何意义。它只检查寄存器的上下边界,如果超出范围则引发#BR
异常。
只有一个操作码,它需要寄存器+内存操作数(在ModR / M r
和r/m
字段中。
objdump -d
首先列出AT&T和Intel语法中的寄存器操作数。
我用NASM组装了db 0x62, 0x2c, 0x24
并将其与ld -melf_i386
链接成一个32位ELF可执行文件(因为我有一个包装器脚本,该脚本使汇编+链接+反汇编比更容易只是组装)。
objdump -drwC -Mintel
8048060: 62 2c 24 bound ebp,QWORD PTR [esp]
objdump -drwC -Matt
8048060: 62 2c 24 bound %ebp,(%esp)
binutils中实现的AT&T语法似乎很奇怪(as
/ objdump
/ gdb
)bound
< em>需要首先列出的寄存器arg。
bound %eax, (%edx) # assembles fine
bound (%edx), %eax # foo.s:2: Error: operand size mismatch for `bound'
我假设它在Intel语法模式下是相同的,它要求寄存器arg为第一个。这里的含义没有歧义,只是一个奇怪的设计选择,即不反转操作数与Intel语法。
相关:AT&T syntax also has "bugs" according to the GAS manual:
9.15.16 AT&T语法错误
在某些情况下,UnixWare汇编程序以及可能是其他AT&T派生的ix86 Unix汇编程序会生成带有反向源和目标寄存器的浮点指令。不幸的是,gcc和可能的许多其他程序都使用了这种相反的语法,因此我们坚持使用它。
例如
fsub %st,%st(3)
结果将
%st(3)
更新为%st - %st(3)
,而不是预期的%st(3) - %st
。所有具有两个寄存器操作数的非交换算术浮点运算都会发生这种情况,其中源寄存器为%st
,而目标寄存器为%st(i)
。
因此,AT&T语法存在实际错误,其中两个命令均有效并且表示不同的东西。我认为我们可以将这个操作数“反转”归类于其中。
ndisasm -b32
将其反汇编为622C24 bound ebp,[esp]
,与Intel手册的操作数顺序相匹配。