我编写了从stdin读取并写入stdout的代码:
#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&amp; T语法转换成汇编代码(.s文件)之后:
.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
它工作正常,但我不确定如何使用普通程序集进行“读取”和“写入”系统调用(即将数字移入某些寄存器并使用“int 0x80”执行系统调用)。 / p>
我的目标是即使使用“-nostdlib”选项进行编译也能使其正常工作。
答案 0 :(得分: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