Как выглядит расположение команды косвенного / прямого вызова в памяти?
Я сравниваю инструкцию косвенного вызова с инструкцией прямого вызова, и я хочу знать расположение (из них в памяти, особенно на платформе x86).
Большое спасибо.
1 ответ
Прямой вызов выглядит как вызов по адресу функции (адрес записан здесь в разделе кода здесь по относительному адресу ff ff ff b5 означает -46 [функция на самом деле расположена в 0x46 байт перед инструкцией вызова])
6d0: e8 b5 ff ff ff callq 68a <subroutine>
В то время как косвенный вызов выглядит как вызов EAX (адрес находится в регистре: здесь rax)
6e4: ff d0 callq *%rax
Пример main.c
#include <stdio.h>
typedef int (*func_t)(void);
int subroutine(){
printf(" I am the subroutine\n");
return 0;
}
int main(int argc, char *argv[])
{
printf("--> Start %s\n", argv[0]);
// Direct call
subroutine();
// Indirect call
func_t f_sub = &subroutine;
f_sub();
return 0;
}
Скомпилируйте и выполните: gcc main.c -o main && ./main
Разбирать: objdump -d main
А вот и разобранные коды операций
00000000000006a1 <main>:
6a1: 55 push %rbp
6a2: 48 89 e5 mov %rsp,%rbp
6a5: 48 83 ec 20 sub $0x20,%rsp
6a9: 89 7d ec mov %edi,-0x14(%rbp)
6ac: 48 89 75 e0 mov %rsi,-0x20(%rbp)
6b0: 48 8b 45 e0 mov -0x20(%rbp),%rax
6b4: 48 8b 00 mov (%rax),%rax
6b7: 48 89 c6 mov %rax,%rsi
6ba: 48 8d 3d e9 00 00 00 lea 0xe9(%rip),%rdi # 7aa <_IO_stdin_used+0x1a>
6c1: b8 00 00 00 00 mov $0x0,%eax
6c6: e8 95 fe ff ff callq 560 <printf@plt>
6cb: b8 00 00 00 00 mov $0x0,%eax
6d0: e8 b5 ff ff ff callq 68a <subroutine>
6d5: 48 8d 05 ae ff ff ff lea -0x52(%rip),%rax # 68a <subroutine>
6dc: 48 89 45 f8 mov %rax,-0x8(%rbp)
6e0: 48 8b 45 f8 mov -0x8(%rbp),%rax
6e4: ff d0 callq *%rax
6e6: b8 00 00 00 00 mov $0x0,%eax
6eb: c9 leaveq
6ec: c3 retq