2016-09-27 195 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'。 –