当您编译 C++ 或任何其他编译语言时,都会有一个优化器以更有效的方式运行和重写一些代码。既然您不编译汇编语言或arm汇编语言,那么是否有优化器正在运行,或者计算机是否完全按照您输入的内容运行?
考虑这个片段是用
nasm -f elf64 -O0
组装的,没有优化
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字节内,因此将其更改为short,从而节省了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 个字节。