Вы разбираете 64-битный код, как если бы это был 32-битный код.Обычно это невозможно, если вы специально не переопределите свой дизассемблер или не используете objcopy
или что-то еще для копирования 64-битного машинного кода в 32-битный объектный файл ELF.
x86-64 перепрофилировали 0x40..fбайты как префиксы REX вместо 1-байтовых кодировок inc / dec.DEC EAX на самом деле является префиксом REX.W, поэтому для обычной установки указателя кадра указывается mov %rsp, %rbp
.
Это также объясняет использование 8 верхних байтов красной зоны под стекомуказатель.(x86-64 System V имеет красную зону, i386 System V - нет; она будет перемещать ESP перед сохранением под ней.) И это объясняет -8
вместо -4
для указателя, потому что x86-64 имеет 8-байтовые указатели.
0
байты, потому что вы разбираете .o
, который не связан.Эти 4 байта нулей будут заполнены абсолютным адресом строки компоновщиком.
GCC использует здесь mov r/m64, sign_extended_imm32
для хранения 8-байтового указателя на память, используя 32-битный абсолютный адрес в качественемедленное.
Чтобы поместить его в регистр, мы получили бы нормальный mov r32, imm32
(с неявным нулевым расширением до 64-битного) для исполняемого файла без PIE.Но этот код (со стандартным -O0
«режимом отладки») требует всего 8-байтового указателя в памяти.Он по-прежнему может использовать 32-разрядный абсолютный адрес вместо REA-относительного LEA в регистре + отдельном хранилище, но это должно быть явным расширением знака до 64-разрядного.