Вопрос

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

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

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

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

Это было полезно?

Решение

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 Syscall, который вы делаете, пока 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.

Другие советы

Iirc int 0x80 Инструкция используется для вызова Syscall с помощью вектора прерывания. В вашем примере значений в ebx и eax используются, чтобы указать, какой SYSCALL вы собираетесь позвонить (вероятно, операция печати на Stdout).

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

На многих системах, int 80h это системный вызов ворота. Номер Syscall находится в 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)

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

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

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

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

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

ebx = вывод (1 = stdout)
ecx = адрес строки
EDX = длина строки

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

http://www.intel.com/assets/ja_jp/pdf/manual/253665.pdf

Раздел 6.4 У него есть некоторые вещи о прерывании и исключениях.

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

Mnemonics/Code Tables Cheatsheet:http://www.jegerlehner.ch/intel/

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top