section .data
msg db 'Press any key to continue...', 0
section .text
global _start
_start:
; 显示消息
mov eax, 4 ; 系统调用号为 4 (write)
mov ebx, 1 ; 文件描述符 1 是标准输出
mov ecx, msg ; 消息字符串的地址
mov edx, 28 ; 消息字符串的长度
int 0x80 ; 调用系统调用
; 等待中断
mov eax, 3 ; 系统调用号为 3 (read)
mov ebx, 0 ; 文件描述符 0 是标准输入
mov ecx, buf ; 输入缓冲区的地址
mov edx, 1 ; 缓冲区的大小
int 0x80 ; 调用系统调用
; 退出程序
mov eax, 1 ; 系统调用号为 1 (exit)
xor ebx, ebx ; 返回值为 0
int 0x80 ; 调用系统调用
上面是Linux下x86(32位)调用write系统调用进行输出的代码,请把“Press any key to continue...”换成自己感兴趣的语句,并进行编译、链接和运行,给出运行截图,画思维导图,说明对系统调用原理的理解和心得体会。
上面的代码是应用于32位,我用的是64位的,所以对于代码需要稍加改动
下面是更改后的代码
.section .data
msg: .ascii "我是边梦梦,请输入...\n"
buf: .ascii "read:" "
.section .text
.global main
main:
# 显示消息
mov $4,%eax # 系统调用号为 4 (write)
mov $1,%ebx # 文件描述符 1 是标准输出
mov $msg,%ecx # 消息字符串的地址
mov $29,%edx # 消息字符串的长度,一个汉字占3个字节
int $0x80 # 调用系统中断
# 等待输入,产生中断
mov $3,%eax # 系统调用号为 3 (read)
mov $0,%ebx # 文件描述符 0 是标准输入
mov $(buf+5),%ecx # 输入缓冲区的地址
mov $64,%edx # 缓冲区的大小
int $0x80 # 调用系统中断
# 显示消息
mov $4,%eax # 系统调用号为 4 (write)
mov $1,%ebx # 文件描述符 1 是标准输出
mov $buf,%ecx # 消息字符串的地址
mov $64,%edx # 消息字符串的长度
int $0x80 # 调用系统调用
# 退出程序
mov $1, %eax # 系统调用号为 1 (exit)
mov $0, %ebx # 返回值为 0
int $0x80 # 调用系统调用
.section .data
msg: .ascii "我是边梦梦,请输入...\n"
buf: .ascii "read:"
这里是为了声明两个变量,.ascii是表示它是一段ascii形式的字符串
buf同理
# 显示消息
mov $4,%eax # 系统调用号为 4 (write)
mov $1,%ebx # 文件描述符 1 是标准输出
mov $msg,%ecx # 消息字符串的地址
mov $29,%edx # 消息字符串的长度,一个汉字占3个字节
int $0x80 # 调用系统中断
这段是为了把msg的“我是边梦梦,请输入...\n” 显示在屏幕上(所以用的是write)
# 等待输入,产生中断
mov $3,%eax # 系统调用号为 3 (read)
mov $0,%ebx # 文件描述符 0 是标准输入
mov $(buf+5),%ecx # 输入缓冲区的地址
mov $64,%edx # 缓冲区的大小
int $0x80 # 调用系统中断
这段是为了在BUF字符串 “read:”后进行键盘输入,所以输入缓冲区的地址buf要+5,进行读取你键盘输入的数据。
此处 mov $64,%edx ,你也可以自行更改大小
# 显示消息
mov $4,%eax # 系统调用号为 4 (write)
mov $1,%ebx # 文件描述符 1 是标准输出
mov $buf,%ecx # 消息字符串的地址
mov $64,%edx # 消息字符串的长度
int $0x80 # 调用系统调用
这段是为了把刚才你的键盘输入的显示到你的屏幕上
最后就是退出程序,就结束啦,这样运行出来的结果就是
这个命令将编译test.S
文件并生成一个名为test
的可执行文件,生成的可执行文件不是一个位置独立的可执行文件。
可以使用./test
命令在终端上运行生成的可执行文件