2016-09-27 166 views
0

当您编译C++或任何其他编译语言时,会有一个优化器以更高效的方式运行并重写一些代码。既然从编译语言的角度来看,您不编译汇编语言或arm汇编语言,有没有优化器在运行,或者计算机是否按照您键入的内容运行?汇编语言优化器

+2

通常在使用ASM进行编程时,您需要确保二进制输出与您编写的完全相同。使用一些伪指令可以让你更轻松一些,例如在固定字RISC CPU上加载立即数,汇编器本身计算出如何分解/合并加载指令以获得最终的常量。但通常不希望机器代码出现意外的修改,因此优化器将毫无意义。 – Ped7g

回答

2

考虑这个片段与nasm -f elf64 -Oo没有优化

section .rodata 
    Prompt: db 'Prompting Text', 0 

     section .text 
     global _start  

    _start: xor  rax, rax 
      mov  rsi, Prompt 
      jmp  Done 
      nop 
      nop 
      nop 
      nop 
    Done: xor  rdi, rdi 
      mov  eax, 60 
      syscall 

生成的目标代码是该组装;

000 4831C0   xor rax,rax 
003 48BE000000000000 mov rsi,0x0 
     -0000 
00D E904000000  jmp qword 0x16 
012 90    nop 
013 90    nop 
014 90    nop 
015 90    nop 
016 4831FF   xor rdi,rdi 
019 B83C0    mov eax,0x3c 
01E 0F05    syscall 
020 

与默认的优化nasm -f elf64和发生的唯一装配的是,汇编出这个跳跃距离为128字节,因此将其改为短,从而节省了3个字节。

00 4831C0   xor rax,rax 
03 48BE000000000000 mov rsi,0x0 
     -0000 
0D EB04    jmp short 0x13 
0F 90    nop 
10 90    nop 
11 90    nop 
12 90    nop 
13 4831FF   xor rdi,rdi 
16 B83C000000  mov eax,0x3c 
1B 0F05    syscall 
1D 

修改源强制优化而不汇编选项被设置

 section .rodata 
    Prompt: db 'Prompting Text', 0 

     section .text 
     global _start  

    _start: xor  eax, eax 
      mov  esi, Prompt 
      jmp  short Done 
      nop 
      nop 
      nop 
      nop 
    Done: xor  edi, edi 
      mov  eax, 60 
      syscall 

,其结果是;

00 31C0    xor eax,eax 
02 BE00000000  mov esi,0x0 
07 EB04    jmp short 0xd 
09 90    nop 
0A 90    nop 
0B 90    nop 
0C 90    nop 
0D 31FF    xor edi,edi 
0F B83C000000  mov eax,0x3c 
14 0F05    syscall 
16 

这是不同的装配不同,但我的观点是@ Ped7g已经指出的那样,最好知道的指令集,所以你写的代码和目标代码之间有直接的关系。

如果你不知道很多指令符号扩展到64位,这就是为什么xor eax, eax产生与xor rax, rax相同的结果,但保存1个字节。

+0

写一个32位寄存器总是[*零*扩展到完整的64位寄存器](http://stackoverflow.com/questions/11177137/why-do-most-x64-instructions-zero-the-upper -Part-对的一32位寄存器)。 (即,高位32位为零)。如果你想要32-> 64的符号扩展名,你必须使用一个指令,例如MOVSXD r64,r/m32。 –

+0

某些汇编程序还将'mov rax,1234'(7字节:REX +操作码+ modRM + imm32)优化为'mov eax,1234'(5字节:操作码+ imm32),但有些汇编器不会。我忘记了它是否适用于MOV,或者如果某些人也会为你优化'xor rax,rax'。 –