我是汇编语言的新手,我正在尝试使用NASM并遵循assembly tutorial of tutorialspoint来学习Linux上的英特尔32位汇编语言。我对这个例子有一些问题:
section .text
global _start ;must be declared for using gcc
_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
我知道是name db 'Zara Ali'
的简写但是
1.如果“name”变量不适合它,它是如何存储在ecx寄存器中的?(我的意思是当我们想在输出中写入Zara Ali时)
1.是否对每个字符重复系统调用(0x80)?
2条答案
按热度按时间lo8azlld1#
回答你的第二个问题。不,系统调用只使用'int 0x80'指令执行一次。然后控制权转移到sys_write,它将所有这些字符写入stdout。此代码中没有jmp指令或循环,从中可以看到代码是顺序执行的,没有跳转(不包括只被调用一次的syscall本身)。
dgiusagp2#
指令
mov ecx, msg
并不移动数组内容,而是将指向变量的指针放入ecx
寄存器。如果要将该地址中的4个字节加载到ecx
中,则需要在该地址周围使用use square brackets:mov ecx, [msg]
。(通常情况下,对于字符串数据,您不会希望这样做,因为这只是较长字符串的value的 * 部分 *,而write(int fd, void *buf, size_t len)
系统调用需要一个指针。)第二,系统调用
0x80
和所有其他使用int
指令进行的系统调用立即将控制权转移到内核,由内核决定如何处理它,在本例中是写入标准输出。简单来说,
mov ecx, msg
把指向变量的指针移动到ecx
中,而不是实际的东西。如果确实想从字符串中加载一个字节,
movzx eax, byte [ecx]
是一种标准方法,它将其零扩展到双字寄存器中。