В x86 (сборка) допустим ли [repz retq]?

У меня есть чрезвычайно простой тестовый двоичный файл, на который я смотрю с помощью 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

person krb686    schedule 06.08.2017    source источник
comment
Очень интересно, вы правы, это дубликат. Для всех, кому интересно, в связанном блоге верхнего ответа на вопрос, указанный Майклом выше, ... эта форма предпочтительнее простой ret либо когда она является целью любой ветви, условной ( jne/je/...) или безусловный (jmp/call/...), или когда он непосредственно следует за условным переходом. Как видно из второй инструкции в этой функции, это действительно цель условного перехода.   -  person krb686    schedule 07.08.2017
comment
gcc -march=intel или любая конкретная арка, отличная от AMD K8/K8, будет просто использовать обычный ret без заполнения, даже если ret является целевой/неудачной ветвью. Например. используйте gcc -O3 -march=native.   -  person Peter Cordes    schedule 07.08.2017
comment
На самом деле вы смотрите на код из стартовых файлов CRT, связанных с вашим исполняемым файлом, который запускается до/после main(). Они не перекомпилируются каждый раз и, вероятно, были скомпилированы с -march=generic по умолчанию или написаны вручную на ассемблере.   -  person Peter Cordes    schedule 07.08.2017