ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

NASM汇编学习系列(1)——系统调用和参数传递

2020-06-22 19:52:19  阅读:626  来源: 互联网

标签:汇编 elf mov helloworld 参数传递 write exit com NASM


0. 说明

  1. 本学习系列代码几乎完全摘自:asmtutor.com,如果英文可以的(也可以用谷歌浏览器翻译看),可以直接看asmtutor.com上的教程
  2. 本学习系列目录地址:https://www.cnblogs.com/whuwzp/p/nasm_contents.html
  3. 系统环境搭建:(我用的是ubuntu18.04.4 server,安装gcc、g++)
sudo apt install nasm
sudo apt install gcc-multilib

1. 完整示例

以下代码摘自:https://asmtutor.com/#lesson1和https://asmtutor.com/#lesson2

; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
 
SECTION .data
msg     db      'Hello World!', 0Ah     ; assign msg variable with your message string
 
SECTION .text
global  _start
 
_start:
 
    mov     edx, 13     ; number of bytes to write - one for each letter plus 0Ah (line feed character)
    mov     ecx, msg    ; move the memory address of our message string into ecx
    mov     ebx, 1      ; write to the STDOUT file
    mov     eax, 4      ; invoke SYS_WRITE (kernel opcode 4)
    int     80h
    
    mov     ebx, 0      ; return 0 status on exit - 'No Errors'
    mov     eax, 1      ; invoke SYS_EXIT (kernel opcode 1)
    int     80h

编译、链接和运行方法:(其实代码中已经写了)

nasm -f elf helloworld.asm -o helloworld # 可以用nasm -h看帮助信息,-f elf是输出32位elf,-f elf64是64
ld -m elf_i386 helloworld.o -o helloworld # ld是链接器,可以用ld -h看帮助信息,-m elf_i386是格式为i386,也有其他的可选
# Run with: 
./helloworld

2. 系统函数调用

Linux的系统调用通过int 80h实现,在此之前需要先要给eax寄存器赋值(opcode,operation code,操作码),例如调用sys_write函数的opcode是4,那么就给eax赋值4:mov eax, 4,类似的sys_exit的opcode为1。

opcode对应的系统调用可以在这个链接上查看:Click here to view an example of a Linux System Call Table and its corresponding OPCODES. (必须翻墙)

我在stackexchange上找到一个网址不用翻墙:https://fedora.juszkiewicz.com.pl/syscalls.html (点击i386那一栏即可)

3. 参数传递

参数分别按照依次传递给ebx, ecx, edx,例如sys_write的系统调用:

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
  1. ebx:第一个参数,文件描述符,1是标准输出(0是标准输入,2是错误),这个就是写入到标准输出,即打印到屏幕
  2. ecx:第二个参数,内存地址,传递的是msg,数据段中的地址(SECTION .data)
  3. edx:把待打印的字符数传递给edx
  1. windows c编程中好像有stdcall等函数调用约定,约定参数传递的顺序,是从右至左还是反之
  2. windows 32位下参数通过压栈的方式传递的

当执行到int 80后,因为opcode是4,所以调用sys_write,然后取ebx、ecx、edx作为参数执行,相当于write(1, msg, 13)

类似的,sys_exit函数为:

#include <unistd.h>
void _exit(int status);

把0传递给ebx,然后执行exit,相当于exit(0)

系统调用的参数列表:可以在linux shell命令行中输入man 2 write man 2 exit查看,man手册第2部分就是关于系统调用的。

标签:汇编,elf,mov,helloworld,参数传递,write,exit,com,NASM
来源: https://www.cnblogs.com/whuwzp/p/nasm_syscall.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有