Is the disassembled code in att syntax guaranteed to generate the same machine code?
Jan Beulich
jbeulich@suse.com
Thu Apr 29 08:31:27 GMT 2021
On 28.04.2021 19:00, Peng Yu wrote:
> On 4/28/21, Jan Beulich <jbeulich@suse.com> wrote:
>> On 28.04.2021 16:26, Peng Yu wrote:
>>>>> Should this be considered a bug?
>>>>
>>>> No.
>>>
>>> The problem is that the `objdump -d` outputs assembly code that may
>>> not generate the same machine code that the assembly code is
>>> disassembled from.
>>>
>>> It is a fair expectation that the disassembled code can generate
>>> exactly the same machine code from which the disassembled code is
>>> derived from. It is fine if you define the `as` output as correct. But
>>> then, I'd suggest fixing the inconsistency in `objdump -d`.
>>
>> There's nothing to fix there. Again - the same insn
>
> I think that we may have defined "same insn" in different ways.
>
>> often has
>> multiple way for being expressed.
>
> For the case "nop eax", there are 8 ways to encode them.
>
> - 0f 1f c0
> - 0f 1f c8
> - 0f 1f d0
> - 0f 1f d8
> - 0f 1f e0
> - 0f 1f e8
> - 0f 1f f0
> - 0f 1f f8
No, these are all different. The second is "nop %ecx" etc. The fact
the the specified register is actually ignore by the insn is
irrelevant here.
> If you check the following table, it is basically because ModR/M reg
> is "don't care". This is the case in which the same insn different
> ways of encoding.
>
> http://ref.x86asm.net/geek64.html#modrm_byte_32_64
>
> But for 2 and 5 below, they are different instructions. Although they
> are both for no operations, they are of different lengths (due to
> different lengths of displacement and various other things), so they
> should not be considered as the same instruction.
>
> 1: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
> 2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
> 3: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
> 4: 0f 1f 84 00 00 00 00 00 nopl 0x0(%rax,%rax,1)
> 5: 66 0f 1f 84 00 00 00 00 00 nopw 0x0(%rax,%rax,1)
2 and 5, while being different instructions, specify the same
operation. Even if you replaced "nop" by e.g. "neg", they would
still specify the same operation (despite the operand no longer
being ignored), and hence an assembler is free to choose any of
the possible encodings. There are ways in some cases to force a
specific encoding to be used (see the pseudo prefixes), but
the disassembler should not (by default) clutter its output with
such information. If there is a need for it in specific cases,
there can be an option enabling such extra output.
>> objdump converts the binary
>> encoding to something human readable. Having as convert that back
>> is only natural to differ from the original if either the insn can
>> be encoded better than it was, or if the insn was encoded in a way
>> that gas is incapable of producing (which would probably be a bug
>> if no symbols are involved).
>
> Again, we don't have the same definition of "same instruction". To me,
> many of them are different instructions unless you encounter "don't
> care" as in "nop eax" example. Otherwise, they are simply not the same
> according to the intel manually, although they may do the same things
> that are not distinguishable to the users.
Right, but that distinction is _not_ what matters to an assembler.
>> The examples you've shown demonstrated nothing that I'd consider in
>> need of fixing. You're yet to demonstrate an actual inconsistency.
>
> If you change nop in my examples to other mnemonics, you should see
> plenty of other examples. I don't understand why you can not see them.
> The only explanation I can see is that you don't use the same
> definition of "same insn" as I explained above.
Correct, because I don't think your definition is applicable here.
Jan
More information about the Binutils
mailing list