2010-07-30 2 views
8

Я изучаю ассемблер на Linux (noobuntu 10.04) я получил следующий код прочь: http://asm.sourceforge.net/intro/hello.htmlАссамблея, привет мир вопрос

section .text 
global _start ;must be declared for linker (ld) 

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

Это просто привет мир. Работает в Linux + вызывает ядро ​​напрямую (по-видимому). Может кто-нибудь объяснить, что здесь происходит? Я думаю, что он читает целые числа в eax & Регистры процессора ebx & ecx, edx data и определяет системный вызов при вызове ядра. Если да, то делают ли разные комбинации целых чисел разные системные вызовы при вызове int 0x80?

Я плохо разбираюсь в man-страницах, но прочитал каждый связанный с ним, я могу найти, какая-либо справочная страница подскажет, какие комбинации определяют, какие системные вызовы?

ЛЮБАЯ помощь приветствуется. Линия по линии объяснения будет удивительно ... -Спасибо заранее Джереми

ответ

7

При вызове int 0x80, ядро ​​выглядит на значении eax регистра, чтобы определить функцию, которую вы хотите позвонить (это " syscall number "). В зависимости от этого числа остальные регистры интерпретируются как конкретные вещи. sys_write вызова ожидает, что регистры должны быть установлены следующим образом:

  • eax содержит 4
  • ebx содержит дескриптор файла
  • ecx содержит адрес данных для записи
  • edx содержит число байт

Дополнительную подробную информацию см. Linux System Calls.

+0

Большое спасибо, это было мое подозрение и, тем не менее, полезно ... Можете ли вы рассказать мне, где я могу узнать больше? Являются ли эти синтаксические целые числа на страницах man? – Jeremy

+0

Чтобы найти номера системных вызовов, вам нужно вникнуть в файлы заголовков исходного кода Linux. В настоящий момент у меня нет машины Linux, поэтому я не могу сказать вам точное местоположение, но это что-то вроде 'include/asm/syscall.h' в исходном дереве ядра. –

+0

большое спасибо, вы были полезны. – Jeremy

0

Слишком много системных вызовов для того, чтобы для каждой из них была другая инструкция на ассемблере.

Вместо этого вы вызываете инструкцию TRAP. Значение eax определяет, какой системный вызов будет вызываться. Другие регистры являются аргументами системного вызова.

Системные вызовы перечислены внутри ядра.

+0

Спасибо. Где именно я просматриваю системные вызовы в ядре? – Jeremy

2
section .text 
global _start ;must be declared for linker (ld) 

Это только заголовок материала, раздел «Текст» из программы сборки является только машинные команды (по сравнению с данными, только для чтения данных, а также секции BSS). Линия global сродни тому, что функция _start является «общедоступной».

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

Из комментариев мы знаем, что мы смотрим на функцию sys_write, поэтому мы можем man 2 write, чтобы получить подробную информацию. Прототип С дает следующие параметры: fd, *buf и count. Начиная с% ebx, мы видим, что они соответствуют (% ebx = fd,% ecx = строка для записи и% edx = длина строки). Тогда, поскольку мы являемся пользовательским процессом, мы должны попросить ядро ​​выполнить вывод. Это делается через интерфейс SYSCALL, а функция write() (по-видимому) задана номером 4. INT 0x80 - это программное прерывание, которое вызывает подпрограмму SYSCALL для ядра Linux.

Вы можете найти фактические номера всех системных вызовов в файлах заголовков Linux (при условии, что вы их установили). В моей системе я проверил /usr/include/sys/syscall.h, ведущий к /usr/include/asm/unistd.h, а затем на /usr/include/asm-i386/unistd.h. Где (я вижу), #define __NR_write 4.

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

Как и в двух последних строках предыдущего сегмента, это только загружает идентификатор системного вызова и выполняет программное прерывание, чтобы выйти из программы (удалить это отображение памяти и очистки).

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

Это раздел данных, он просто описывает переменные, которые мы использовали в нашей программе.

+0

самый полезный ответ еще. большое спасибо за ваше время. – Jeremy

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