您现在的位置是:首页 > 文章详情

nasm示例一:调用syscall打印Hello World

日期:2018-06-08点击:635

  • NASM是基于英特尔 x86 架构的汇编与反汇编工具。
  • syscall是x86_64架构中专门做系统调用的指令,可参考syscall

1、示例

foo.nasm内容
 global _start section .text _start: mov rax, 1 ; sys_write的系统调用编号为1 mov rdi, 1 ; 文件句柄1对应stdout mov rsi, msg ; 要输出的字符串地址 mov rdx, msglen ; 要输出的字符串长度 syscall ; 系统调用 mov rax, 60 ; sys_exit的系统调用编号为60 xor rdi, rdi ; exit 0 syscall section .data msg: db "Hello, World!", 10 ; ascii表中10对应换行符 msglen: equ $ - msg ; $ 等于当前行开头的地址
编译
nasm -felf64 foo.asm && ld -o foo foo.o
运行结果
[root@localhost nasm]# ./foo Hello, World!

2、代码解释

2.1、syscall

x86平台syscall指令的参数、返回值与寄存器的对应关系

Syscall # Param 1 Param 2 Param 3 Param 4 Param 5 Param 6
rax rdi rsi rdx r10 r8 r9
Return value
rax

在linux系统中也可通过man syscall的方式查看
各平台系统调用指令和返回值对应寄存器
9f2aa3cc8b696daa1b3cf5bf41f9f45f2502ca59
系统调用参数对应寄存器
2bfdaf67ff8a7e797e650d090a089de09f427428
在linux平台write函数对应系统调用为sys_write,对应的syscall编号可在 arch/x86/entry/syscalls/syscall_64.tbl中查看
1 common write sys_write 60 common exit sys_exit
sys_write和sys_exit的定义为
asmlinkage long sys_write(unsigned int fd, const char __user *buf, size_t count); asmlinkage long sys_exit(int error_code); 

2.2、sys_exit

 mov rax, 60 ; sys_exit的系统调用编号为60 xor rdi, rdi ; exit 0 syscall
语句 xor rdi, rdi 将rdi寄存器值设置为0,至于为什么不使用 mov rdi, 0 可参考 Does using xor reg, reg give advantage over mov reg, 0?,程序运行效果为
[root@localhost nasm]# nasm -felf64 foo.asm && ld -o foo foo.o [root@localhost nasm]# ./foo Hello, World! [root@localhost nasm]# echo $? 0
如果修改sys_exit系统调用的参数,那么程序运行的退出结果也会发生变化,如修改为
 mov rdi, rax mov rax, 60 ; sys_exit的系统调用编号为60 syscall
则程序退出码为sys_write的返回值,因为字符串msg长度为14,所以程序运行的退出码也为14
[root@localhost nasm]# nasm -felf64 foo.asm && ld -o foo foo.o [root@localhost nasm]# ./foo Hello, World! [root@localhost nasm]# echo $? 14

2.3、字符串长度计算

在nasm中 $ 等于当前行开头的地址, $$ 等于当前section的开头地址,可参考 https://www.nasm.us/doc/nasmdoc3.html 的3.5 Expressions内容

NASM supports two special tokens in expressions, allowing calculations to involve the current assembly position: the $ and $$ tokens. $ evaluates to the assembly position at the beginning of the line containing the expression; so you can code an infinite loop using JMP $. $$ evaluates to the beginning of the current section; so you can tell how far into the section you are by using ($-$$).





原文链接:https://yq.aliyun.com/articles/601007
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章