Когда вы запускаете int 0x80
, ваша программа прерывается, и ядро проверяет состояние регистров. Начиная с eax
он получает номер системного вызова, который вы хотите выполнить, а из других регистров получает дополнительные данные. Например, для системного вызова write
он извлекает дескриптор файла из ebx
, указатель на буфер, который вы хотите записать из ecx
, и количество байтов, которое вы хотите записать из edx
. Ядро не знает, каковы ваши намерения, оно просто тупо захватывает то, что находится в регистрах, поэтому оно имеет значение, какие регистры вы используете.
Однако, в общем, не имеет значения, какие регистры вы используете для каких значений. В вашем собственном коде вы можете использовать почти все регистры (за исключением таких, как регистры как esp
) для любых целей, которые вы хотите, если вы не взаимодействуете с кодом других людей.
Единственное место, где важно, какие регистры используются, это когда вы хотите взаимодействовать с кодом, написанным другими людьми, например, при вызове функций или операционной системы или при написании функций, которые будут вызываться другими. В таких случаях вы должны установить соответствующие регистры на ожидаемые значения или, возможно, сохранить их содержимое.
Например, когда вы пишете функцию, вызываемую кодом других людей, ожидается, что вы вернете результат своей функции в eax
и сохраните содержимое регистров ebx
, esi
, edi
esp
и ebp
. Если вы используете эти регистры для своих собственных целей, вы должны сначала сохранить их значения где-нибудь (например, в стеке) и восстановить их до их исходных значений перед возвратом.
Существуют также некоторые инструкции, которые ожидают наличия операндов в определенных регистрах (например, stos
или idiv
), но для большинства инструкций вы можете выбирать любые регистры, которые вы хотите.
В тех случаях, когда это имеет значение, правила, для которых используются регистры, записываются в документе Application Binary Interface (ABI) . Этот документ может пониматься как соглашение между всеми программистами относительно того, какие данные ожидать, в какие регистры при вызове функций или операционной системы. Строгое соблюдение ABI необходимо для правильной работы вашего кода при вызове / вызове по чужому коду.
На i386, архитектуре, для которой вы сейчас программируете, Linux использует i386 SysV ABI . Как правило, каждая операционная система использует разные ABI для каждой архитектуры, поэтому перед написанием кода для новой операционной системы или архитектура обязательно проверьте соответствующий ABI.