2016-09-27 9 views
0

コンパイルされたC++または他のコンパイルされた言語をコンパイルするときには、より効率的な方法でコードの一部を実行して書き換えるオプティマイザがあります。コンパイルされた言語を実行するという意味でアセンブリまたはアームアセンブリをコンパイルしないので、オプティマイザが実行されているか、コンピュータが入力したものとまったく同じように実行されますか?アセンブリ言語オプティマイザ

+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で実装および起こった唯一のものは、それが短いにそれを変更して、アセンブラはこのように3つのバイトを保存し、ジャンプは128バイト以内であることが数字ということです。

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, eaxxor rax, raxと同じ結果が得られますが、1バイトは保存されます。

+0

32ビットレジスタを常に書く[*ゼロ* - 完全な64ビットレジスタに追加](http://stackoverflow.com/questions/11177137/why-do-most-x64-instructions-zero-the-upper -32ビットレジスタの一部)。 (すなわち、上位32ビットをゼロにする)。 32-> 64符号拡張を使用するには、命令を使用する必要があります。 MOVSXD r64、r/m32。 –

+0

一部のアセンブラは 'mov rax、1234'(7バイト:REX + opcode + modRM + imm32)を' mov eax、1234'(5バイト:opcode + imm32)に最適化します。私はそれがMOVのためだけであるかどうか、あるいはあなたのために 'xor rax、rax 'も最適化するかどうかを忘れてしまいます。 –