У меня есть чрезвычайно простой тестовый двоичный файл, на который я смотрю с помощью objdump. Я вижу инструкцию по сборке, которая меня смущает. Код выглядит следующим образом:
int main(int argc, char* argv[]){
return 42;
}
Когда я делаю objdump -d test
, я вижу интересную функцию:
00000000004004a0 <__do_global_dtors_aux>:
4004a0: 80 3d 85 0b 20 00 00 cmpb $0x0,0x200b85(%rip) # 60102c <_edata>
4004a7: 75 11 jne 4004ba <__do_global_dtors_aux+0x1a>
4004a9: 55 push %rbp
4004aa: 48 89 e5 mov %rsp,%rbp
4004ad: e8 7e ff ff ff callq 400430 <deregister_tm_clones>
4004b2: 5d pop %rbp
4004b3: c6 05 72 0b 20 00 01 movb $0x1,0x200b72(%rip) # 60102c <_edata>
4004ba: f3 c3 repz retq
4004bc: 0f 1f 40 00 nopl 0x0(%rax)
Итак, 2-я снизу, инструкция f3 c3
или repz retq
. Теперь, глядя на f3
в справочнике по набору инструкций x86, я вижу, что это устаревший префикс.
Таким образом, c3 / ret
, безусловно, не является одной из перечисленных допустимых инструкций, чтобы она предшествовала ей, поэтому мне интересно, почему мой двоичный файл вообще это делает.
Я выполняю gcc(4.8.5) следующим образом:
gcc -g -Wall -c src/test.c -o obj/test.o
gcc -g -Wall obj/test.o -o bin/test
gcc -march=intel
или любая конкретная арка, отличная от AMD K8/K8, будет просто использовать обычныйret
без заполнения, даже еслиret
является целевой/неудачной ветвью. Например. используйтеgcc -O3 -march=native
. - person Peter Cordes   schedule 07.08.2017main()
. Они не перекомпилируются каждый раз и, вероятно, были скомпилированы с-march=generic
по умолчанию или написаны вручную на ассемблере. - person Peter Cordes   schedule 07.08.2017