Проблема сборки с простой программой - PullRequest
2 голосов
/ 06 ноября 2010

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

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» Но я даже не знаю, что происходит на любом из этапов. Первые два этапа помещают длину сообщения и сообщения в два регистра, которые никогда не используются снова. Я не понимаю почему.

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

Ответы [ 4 ]

3 голосов
/ 06 ноября 2010

int 80 - это механизм в некоторых * a 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.

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

1 голос
/ 06 ноября 2010

Во многих системах int 80h является системным вызовом gate. Номер системного вызова в 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)
1 голос
/ 06 ноября 2010

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

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

0 голосов
/ 06 ноября 2010

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

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

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

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

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

ebx = output (1 = stdout)
ecx = адрес строки
edx = длина строки

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

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

Раздел 6.4 В нем есть кое-что о прерываниях и исключениях.

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

Таблица таблиц мнемоники / кодовых таблиц: http://www.jegerlehner.ch/intel/

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

...