2010-11-06 4 views
2

Я пытаюсь изучить сборку с нуля. Я читал совсем немного, но даже следующая простая программа, которую я нашел в справочнике есть я озадачен:Проблема сборки с простой программой

section .data 
msg db "Hello!", 0xa 
len equ $ - msg 
section .text 

    global _start 

_start: 


move edx, len 
move ecx, msg 
move ebx, 1 
move eax, 4 
int 0x80 
move ebx, 0 
move eax, 1 
int 0x80 

Теперь, видимо, это, как предполагается печатать «Hello». Но я даже не знаю, что происходит на любой стадии. Первые два этапа помещают длину сообщения и messgae в два регистра, которые никогда не используются снова. Я не понимаю, почему.

Я не знаю, почему нужны четыре разных регистра.

+0

Книга для какого процессора? Какой процессор вы используете? – Oded

+2

Я уверен, что это для процессоров x86. – 2010-11-06 14:19:09

ответ

3

int 80 механизма в некотором * а UNIX-подобные операционные системы для создания системных вызовов.

Для этих вызовов регистры используются для определенных значений. Из syscalls файла:

0 STD NOHIDE { int nosys(void); } syscall nosys_args int 
1 STD NOHIDE { void exit(int rval); } exit rexit_args void 
2 STD POSIX { int fork(void); } 
3 STD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); } 
4 STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); } 

вы можете увидеть, что число 4 является write вызовом и нуждается в три других параметрах. Номер 1 - exit и ему нужен только код возврата.

При выполнении вызова eax это системный вызов, который вы делаете в то время как ebx, ecx и edx являются три параметра (при условии, что все они необходимы - exit, например, требуется только один).

Таким образом, вы можете прокомментировать код следующим образом:

move edx, len ; length of message (nbyte). 
move ecx, msg ; message to print (buf). 
move ebx, 1  ; file handle 1, stdout (fd). 
move eax, 4  ; write syscall. 
int 0x80  ; do it. 

move ebx, 0  ; exit code (rval). 
move eax, 1  ; exit syscall. 
int 0x80  ; do it. 

* а: Более поздние версии Linux представила новый интерфейс, который может использовать различные методы, на основании которых обеспечивает лучшую скорость , Например, некоторые чипы Intel намного быстрее, если вы используете sysenter, а не int 80.

+0

Итак, когда я делаю int 80, любые команды в любых регистрах выполняются? – 2010-11-06 15:09:14

+0

Нет, eax решает, что происходит, другие регистры - это дополнительная информация, которая может понадобиться для конкретного syscall, указанного eax. – paxdiablo

+0

Так что eax, ebx, ecx и edx не являются «общими», как я полагал, у них разные цели? Я не мог сделать move eax, msg? – 2010-11-06 15:26:23

1

Инструкция IIRC int 0x80 используется для вызова системного вызова с использованием вектора прерывания. В вашем примере значения в ebx и eax используются для указания того, какой вызов вы хотите вызвать (возможно, операция печати на stdout).

Schnall знает, что в случае, если edx и ecx должны содержать то, что собираетесь напечатать.

1

Во многих системах int 80h является воротами system call. Номер системного вызова находится в eax. ebx, ecx и edx содержат дополнительные параметры:

move edx, len 
move ecx, msg 
move ebx, 1 ; fd 1 is stdout 
move eax, 4 ; syscall 4 is write 
int 0x80  ; write(1, msg, len) 
move ebx, 0 
move eax, 1 ; syscall 1 is exit 
int 0x80  ; exit(0) 
+0

Спасибо за ваш ответ. Итак, что движет ebx, 0 и move eax, 1 do? И еще один вопрос: зачем мне указывать длину сообщения? – 2010-11-06 14:12:56

+0

'ebx' - это параметр, переданный' exit() ', то есть' 0' (успех). Вы должны указать длину сообщения, потому что 'write()' работает с произвольными двоичными данными, а не с нулевыми символами. –

+0

Я был под впечатлением eax, ebx, ecx и edx были реестрами генеалогических целей. В чем разница между их использованием? – 2010-11-06 14:20:15

0

Когда вы вызываете системный вызов, мнемоника 'int' генерирует системное прерывание. Он как бы «перескакивает» на системную функцию, которая в этом случае выводит вывод (зависит от eax).

Это прерывание использует все эти регистры, чтобы знать, что делать. Прерывание считывает eax, проверяет, какую функцию вы хотите, и использует другие регистры для этого.

eax - номер функции, 4 означает sys_write, который записывает строку в дескриптор потока/файла.

Теперь он знает, что вы хотите что-то написать в каком-то месте, затем он использует другие регистры для этих сведений.

для EAX = 4 и INT 0x80 это значение для других регистров:

EBX = выход (1 = стандартный вывод)
ECX = адрес строки
EDX = длина строки

Вы можете прочитать:

http://www.intel.com/Assets/ja_JP/PDF/manual/253665.pdf

Раздел 6.4 Он имеет некоторые вещи о Int erruptins и Exceptions.

И вы можете начать писать Intel код 80x86 сборки, который проще и легче понять, вот некоторые ссылки:

Мнемоника/Код таблицы шпаргалка: http://www.jegerlehner.ch/intel/

Некоторые вводные сайты: http://mysite.du.edu/~etuttle/math/8086.htm http://www.malware.org/teaching/assembly.htm

+0

Спасибо. Я буду жадно изучать все три ссылки! – 2010-11-06 15:09:49

Смежные вопросы