2014-12-03 2 views
1

Я написал код, который считывает из стандартного ввода и записи в стандартный вывод:X86: создание системных вызовов, не ссылаясь на стандартную библиотеку

#include <stdio.h> 
#include <unistd.h> 

int main() /* copy input to output */ 
{ 
    char buf[BUFSIZ]; 
    int n; 

    while ((n = read(0, buf, BUFSIZ)) > 0) 
     write(1, buf, n); 

    return 0; 
} 

После того как я преобразован в код сборки (а .с файл) в 32- бит AT & T синтаксис:

.text 
    .globl _start 
_start: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp #16 bit alignment 
    subl $8224, %esp #space for local variables 
    jmp _READ 
_WRITE: 
    movl 8220(%esp), %eax 
    movl %eax, 8(%esp) 
    leal 28(%esp), %eax 
    movl %eax, 4(%esp) 
    movl $1, (%esp) 
    call write 
    int $0x80 
_READ: 
    movl $8192, 8(%esp) #buffer length 
    leal 28(%esp), %eax 
    movl %eax, 4(%esp) 
    movl $0, (%esp) 
    call read 
    movl %eax, 8220(%esp) 
    cmpl $0, 8220(%esp) 
    jg _WRITE 
    movl $0, %eax 
    leave 
    ret 

Он отлично работает, но я не уверен, как делает «ИНТ«читать»и«писать»системные вызовы с помощью простой сборки (т.е. движущихся чисел в определенных регистрах и использовать 0x80 "для выполнения системных вызовов).

Моя цель - заставить его работать, даже если он скомпилирован с опцией «-nostdlib».

+0

Системные вызовы зависит от операционной системы. Укажите свою ОС. –

+0

linux :) @Raymond Chen – Meteorite

+0

Я бы рекомендовал начать с [x86 вызовов] (http://en.wikipedia.org/wiki/X86_calling_conventions), а позже спросить более конкретно. Как называть ОС, зависит от используемой ОС. Linux? – alexander

ответ

3

Подсказка: архитектура x86 старая, медленная, странная и устаревшая. Вместо этого вы должны использовать amd64.

Список системных вызовов доступен в Linux исходный код:

https://github.com/torvalds/linux/blob/master/arch/x86/syscalls/syscall_32.tbl

Система номер вызова идет в EAX. Последовательность параметров - это всегда ebx, ecx, edx, esi, edi, ebp. Так код становится:

 .text 
     .globl _start 
    _start: 
     pushl %ebp 
     movl %esp, %ebp 
     andl $-16, %esp #16 bit alignment 
     subl $8224, %esp #space for local variables 
     jmp _READ 
    _WRITE: 
     movl 8220(%esp), %edx 
     leal 28(%esp), %ecx 
     movl $1, %ebx 
     movl $4, %eax 
     int $0x80 
    _READ: 
     movl $8192, %edx #buffer length 
     leal 28(%esp), %ecx 
     movl $0, %ebx 
     movl $3, %eax 
     int $0x80 
     movl %eax, 8220(%esp) 
     cmpl $0, 8220(%esp) 
     jg _WRITE 
     movl $1, %eax 
     movl $0, %ebx 
     int $0x80 

Сборка и связь с:

$ as --32 hel.s -o hel.o 
$ ld -melf_i386 hel.o -o hel 

http://www.linuxjournal.com/article/4048