为什么 Solaris 汇编器生成的机器代码与此处的 GNU 汇编器不同? [英] Why does the Solaris assembler generate different machine code than the GNU assembler here?

查看:29
本文介绍了为什么 Solaris 汇编器生成的机器代码与此处的 GNU 汇编器不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 amd64 编写了这个小程序集文件.代码做什么对于这个问题并不重要.

I wrote this little assembly file for amd64. What the code does is not important for this question.

        .globl fib

fib:    mov %edi,%ecx
        xor %eax,%eax
        jrcxz 1f
        lea 1(%rax),%ebx

0:      add %rbx,%rax
        xchg %rax,%rbx
        loop 0b

1:      ret

然后我继续在 Solaris 和 Linux 上进行汇编和反汇编.

Then I proceeded to assemble and then disassemble this on both Solaris and Linux.

$ as -o y.o -xarch=amd64 -V y.s                            
as: Sun Compiler Common 12.1 SunOS_i386 Patch 141858-04 2009/12/08
$ dis y.o                                                  
disassembly for y.o


section .text
    0x0:                    8b cf              movl   %edi,%ecx
    0x2:                    33 c0              xorl   %eax,%eax
    0x4:                    e3 0a              jcxz   +0xa      <0x10>
    0x6:                    8d 58 01           leal   0x1(%rax),%ebx
    0x9:                    48 03 c3           addq   %rbx,%rax
    0xc:                    48 93              xchgq  %rbx,%rax
    0xe:                    e2 f9              loop   -0x7      <0x9>
    0x10:                   c3                 ret    

Linux

$ as --64 -o y.o -V y.s
GNU assembler version 2.22.90 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.22.90.20120924
$ objdump -d y.o

y.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <fib>:
   0:   89 f9                   mov    %edi,%ecx
   2:   31 c0                   xor    %eax,%eax
   4:   e3 0a                   jrcxz  10 <fib+0x10>
   6:   8d 58 01                lea    0x1(%rax),%ebx
   9:   48 01 d8                add    %rbx,%rax
   c:   48 93                   xchg   %rax,%rbx
   e:   e2 f9                   loop   9 <fib+0x9>
  10:   c3                      retq   

生成的机器码怎么不一样了?Sun as 为 mov %edi,%ecx 生成 8b cf 而 gas 为相同的指令生成 89 f9 .这是因为在x86下对同一条指令进行编码的方式多种多样,还是这两种编码真的有特别的区别?

How comes the generated machine code is different? Sun as generates 8b cf for mov %edi,%ecx while gas generates 89 f9 for the very same instruction. Is this because of the various ways to encode the same instruction under x86 or do these two encodings really have a particular difference?

推荐答案

一些 x86 指令有多种编码,可以做同样的事情.特别是,任何作用于两个寄存器的指令都可以交换寄存器并反转指令中的方向位.

Some x86 instructions have multiple encodings that do the same thing. In particular, any instruction that acts on two registers can have the registers swapped and the direction bit in the instruction reversed.

给定的汇编器/编译器选择哪一个完全取决于工具作者选择的工具.

Which one a given assembler/compiler picks simply depends on what the tool authors chose.

这篇关于为什么 Solaris 汇编器生成的机器代码与此处的 GNU 汇编器不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆