section .data:
msg: db "Hello !"
msglen: equ $-msg
section .text:
global _start:
_start:
mov ebx,msg
mov ecx,msglen
mov eax,4
int 80h
mov eax,1
int 80h
上面的代码不起作用。 但是下面的代码运行良好。
section .data:
msg: db "Hello !"
msglen: equ $-msg
section .text:
global _start:
_start:
mov ecx,msg
mov edx,msglen
mov eax,4
int 80h
mov eax,1
int 80h
我所做的全部就是将ebx更改为ecx,将ecx更改为edx。 这是怎么回事?
答案 0 :(得分:3)
您的第二个代码有效,因为write(0, "string", len)
起作用了。 FD 0是标准输入,但是在终端程序中,通常使用所有3个标准FD来运行程序,它们引用在TTY上以读/写方式打开的同一文件描述。
因此,除非将其重定向到文件,否则您可以写到stdin。
在您的_start
入口点进入用户空间之前,内核将所有regs归零,因此,如果未设置,则EBX = 0。 write(2)
将文件描述符作为其第一个参数。
使用strace ./a.out
查看系统调用。
您的第一个代码不起作用,因为write("string", len, 0)
传递了一个指针作为文件描述符编号,因此sys_write
将返回-EBADF
(或者-EFAULT
,如果它检查{ {1}}首先是有效指针)。除非使用len
之类的重定向来打开fd ./a.out 12345>&1
作为12345
的副本,否则唯一有效的fds将是0、1或2。再次使用1
。
并阅读有关系统调用调用约定的文档。 What are the calling conventions for UNIX & Linux system calls on i386 and x86-64有链接。
另请参阅https://stackoverflow.com/tags/x86/info,以获取更多文档/手册和指南的链接。