Что такое инструкция callq?
У меня есть некоторый код ассемблера gnu для архитектуры x86_64, генерируемой инструментом, и есть следующие инструкции:
movq %rsp, %rbp
leaq str(%rip), %rdi
callq puts
movl , %eax
Я не могу найти актуальную документацию по инструкции "callq".
Я посмотрел на http://support.amd.com/TechDocs/24594.pdf который является "amd64 Architecture Programmer's Manual Volume 3: Общие и системные инструкции", но они описывают только ближние и дальние инструкции вызова.
Я посмотрел на документация для GNU assembler https://sourceware.org/binutils/docs/as/index.html но не удалось найти раздел с подробными инструкциями, которые он поддерживает.
Я понимаю, что это вызов функции, но я хотел бы знать подробности. Где я могу их найти?
2 ответов
это просто call
. Используйте разборку синтаксиса Intel, если вы хотите иметь возможность просматривать инструкции в руководствах Intel/AMD.
на q
технически применяется суффикс размера операнда (он толкает 64-разрядный обратный адрес и обрабатывает RIP как 64-разрядный регистр), но нет способа переопределить его префиксами инструкций. т. е. calll
и callw
не encodeable в 64-битном режиме, так что это просто раздражает, что некоторые в&инструменты синтаксис t показывают его как из call
. Это конечно относится к retq
как хорошо.
различные инструменты различны в 32 против 64-разрядного режима. ( Godbolt)
- gcc-S: всегда
call
/ret
. Милый. - clang-S:
callq
/retq
иcalll
/retl
. По крайней мере, это постоянно раздражает. -
objdump-d:
callq
/retq
(явные 64-bit) иcall
/ret
(неявно для 32-разрядной версии). Непоследовательно и глупо, потому что 64-бит не имеет выбора размера операнда, но 32-бит делает это. (Не полезное выбор, хотя:callw
усекает EIP до 16 бит.)хотя, с другой стороны, размер операнда по умолчанию (без Рекса.W префикс) для большинство инструкции в 64-битном режиме по-прежнему 32. Но!--18--> нужен суффикс размера операнда; ассемблер не выберет 32-бит для вас, если ничего не подразумевает. OTOH,
push
неявноpushq
, хотяpushw
иpushq
несколько как encodeable (и может использоваться на практике) в 64-разрядном режиме.
из руководства по эксплуатации Intel (см. выше):
для ближайшего абсолютного вызова абсолютное смещение указывается косвенно в регистре общего назначения или в ячейке памяти (r/m16, r/m32 или r/m64). Атрибут operand-size определяет размер целевого операнда (16, 32 или 64 бита). в 64-разрядном режиме размер операнда для ближнего вызова (и всех ближних ветвей) принудительно 64-бит.
для rel32 ... Как и в случае абсолютных смещений, атрибут размера операнда определяет размер целевого операнда (16, 32 или 64 бита). в 64-битном режиме целевой операнд всегда будет 64-битным, потому что размер операнда вынужден 64-бит для ближних ветвей.
в 32-битном режиме, вы можете кодировать 16-битный call rel16
это усекает EIP до 16 бит, или call r/m16
что использует абсолютный 16-битный адрес. Но, как говорится в руководстве, размер операнда фиксируется в 64-битном режиме.
callq относится к перемещаемому вызову в общих библиотеках / динамических библиотеках. Идея-push 0, затем нажмите символ поиска, затем вызовите функцию, чтобы найти ее при первом вызове. В перемещаемой таблице программы он заменяет вызов на фактическое местоположение функции при первом вызове функции. Последующие вызовы относятся к таблице перемещения, созданной во время выполнения.