Когда программа запускается (linux, elf) - есть ли нули в eax
, ebx
и т.д. или может быть что угодно (я не делаю никаких вызовов и не использую внешние библиотеки)? На моей машине это действительно так, могу ли я использовать такое поведение при написании asm-программ?
Какое состояние регистра по умолчанию при запуске программы (asm, linux)?
Ответы (3)
Это полностью зависит от ABI для каждой платформы. Поскольку вы упомянули eax
и ebx
, давайте посмотрим, что происходит с x86. В fs/binfmt_elf.c
строке # 972 внутри load_elf_binary()
ядро проверяет, указывает ли ABI какой-либо требования к значениям регистров при загрузке программы:
/*
* The ABI may specify that certain registers be set up in special
* ways (on i386 %edx is the address of a DT_FINI function, for
* example. In addition, it may also specify (eg, PowerPC64 ELF)
* that the e_entry field is the address of the function descriptor
* for the startup routine, rather than the address of the startup
* routine itself. This macro performs whatever initialization to
* the regs structure is required as well as any relocations to the
* function descriptor entries when executing dynamically links apps.
*/
Затем он вызывает ELF_PLAT_INIT
, который является макросом, определенным для каждой архитектуры в arch/xxx/include/elf.h
. Для x86 он выполняет следующие:
#define ELF_PLAT_INIT(_r, load_addr) \
do { \
_r->bx = 0; _r->cx = 0; _r->dx = 0; \
_r->si = 0; _r->di = 0; _r->bp = 0; \
_r->ax = 0; \
} while (0)
Итак, когда ваш статически связанный двоичный файл ELF загружается в Linux x86, вы можете рассчитывать, что все значения регистров будут равны нулю. Однако это не значит, что вам следует. :-)
Динамическое связывание
Обратите внимание, что выполнение динамически связанного двоичного файла фактически запускает код динамического компоновщика в вашем процессе до того, как выполнение достигнет вашей _start
(точки входа ELF). Это может и действительно оставляет мусор в регистрах, как разрешено ABI. За исключением, конечно, указателя стека ESP / RSP и atexit
перехватчика EDX / RDX.
_start
и оставляет мусор в регистрах, как это разрешено ABI. Регистры только статически связанных исполняемых файлов обнуляются, когда выполнение достигает _start
.
- person Peter Cordes; 18.09.2017
Для систем AMD64 или x86-64 (64 бит) в Linux x86-64 ABI определяет исходное содержимое регистров.
Аналогичные спецификации существуют для i386 ABI, ARM ABI и т. д.
См. Страницы википедии в ELF и ABI
x86-64 System V ABI
3.4.1 Начальный стек и состояние регистрации (Basile связан с PDF-версией этого):
- # P3 #
# P4 #
- # P5 #
# P6 #
- # P7 #
# P8 #
Все остальное не определено.
Затем за ним следует Linux, потому что так сказано в LSB.
%rdx
может быть NULL, а в текущем Linux это 0
в новом процессе из статически связанного исполняемого файла. Но динамический компоновщик запускается до _start
при выполнении динамически связанного исполняемого файла, поэтому он может установить значение в %rdx
(и это делает, согласно gdb /bin/bash
). Я не уверен, должен ли _start
по-прежнему рассматривать его как указатель на функцию в этот момент, но, вероятно, да, потому что все остальное в этот момент следует за ABI.
- person Peter Cordes; 18.09.2017
%esp
, %edx
, %ebp
, а все остальное не определено.
- person pts; 05.01.2018