AT&T 汇编-11: 使用系统调用

前面使用系统调用 write() 来输入输出。一般来说,在 /usr/include/asm/unistd.h 可以找到可用的系统调用的定义(在我的机器上实际是 unistd_32.h):

...
#define __NR_restart_syscall      0
#define __NR_exit                 1
#define __NR_fork                 2
#define __NR_read                 3
#define __NR_write                4
#define __NR_open                 5
#define __NR_close                6
...

定义了系统调用和各自对应的值。

使用系统调用前要把对应的系统调用值放到 eax 中,再把需要的参数放到对应的位置,最后使用中断 int $0x80 使用系统调用。如果系统调用的参数小于 6 个,参数的顺序依次是:ebx,ecx,edx,esi,edi。如果系统调用的参数超过 6 个,则把参数内存位置的地址放到 ebx 中,输入的参数按照顺序连续存放。系统调用的返回值存放在 eax 中。

使用 c 程序时,参数通过栈传递,返回值也是放在 eax 中。

# syscall.s

.section .rodata
msg1:
   .ascii   "Hello, world.\n"
msg2:
   .asciz   "write str len = %d.\n"
msg3:
   .asciz   "printf str len = %d.\n"

.section .text
.globl main
main:
   movl  $4,      %eax    # system call
   movl  $1,      %ebx    # file descriptor
   movl  $msg1,   %ecx    # string address
   movl  $msg2,   %edx
   subl  $msg1,   %edx    # string length
   int   $0x80

   pushl %eax
   pushl $msg2
   call  printf
   addl  $8,   %esp

   pushl %eax
   pushl $msg3
   call  printf
   addl  $8,   %esp

   movl  $1, %eax
   movl  $0, %ebx
   int   $0x80

第 35-40 行使用了 1 号系统调用 write() 向屏幕输出一串字符串。根据定义,write() 的返回值(输出的字符数)存放在 eax 中。接着第 21-23 行使用 c 标准库函数 printf() 打印 eax 的值,printf() 的返回值(输出的字符数)也存放在 eax 中。最后第 26-28 行打印 printf() 的返回值。

发表于 2011年7月5日
本文目前尚无任何评论.

发表评论

XHTML: 您可以使用这些标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>