调用"系统调用函数write"的两种实现

我们知道调用“系统调用”有两种方式。
( 1) 将系统调用指令封装为 c库函数,通过库函数进行系统调用,操作简单。
(2)不依赖任何库函数,直接通过汇编指令 int与操作系统通信。

我们平常写的C语言用的就是第一种系统调用,通过函数调用write函数,我们下面用汇编语言来重写一下,利用我们定义的simu_write函数来更好的探究write函数的运作机理

syscall.S

section .data
str_c_lib: db "c library says: hello world",0xa
str_c_lib_len equ $-str_c_lib
section .text
global _start
_start:

;;;模拟c语言;;

	push str_c_lib_len
	push str_c_lib
	push 1     ;是push到标准输出,也是一个参数

	call simu_write
	add esp,12
	
	;;;退出程序,不然会出现段错误;;
	mov eax,1
	int 0x80
	
simu_write:
	push ebp
	mov ebp,esp
	mov eax,4
	mov ebx,[ebp+8]
	mov ecx,[ebp+12]
	mov edx,[ebp+16]

	int 0x80
	pop ebp
	ret

我们简单的来解释一下这一种方法:其先通过函数调用约定,从右向左往栈中压入参数str_c_lib_len,str_c_lib,1,(write(1,str_c_lib,str_c_lib_len))然后调用simu_write函数

在我们的simu_write函数中先保存旧的ebp,然后调用第4号子功能:write系统调用,将其存放在eax中,然后分别放入参数。这里也就是我们所说的第二种系统调用了,不过我们先不在这里说,在下一个程序中说。

完成这些后,通过

mov eax,1
int 0x80

退出程序。其中第1号子功能是exit
int 0x80 发起中断,通知 Linux完成请求的功能,即完成退出请求

好,让我们来看第二种方法,绕过库函数,直接与OS通信

预备知识:
系统调用输入参数的传递方式:
当输入的参数小于等于 5 个时, Linux 用寄存器传递参数。当参数个数大于 5 个时,把参数按照顺序 放入连续的内存区域,并将该区域的首地址放到 ebx 寄存器。这里我们只演示参数小于等于 5 个的情况。 eax寄存器用来存储子功能号(寄存器 eip、 ebp、 esp是不能使用的)。 5个参数存放在以下寄存器中,
传送参数的顺序如下。
(1) ebx存储第 1个参数。
(2) ecx存储第 2个参数。
(3) edx存储第 3个参数。
(4) esi存储第 4个参数。
(5) edi存储第 5个参数。

程序如下:

section .data

str_syscall: db "syscall says: hello world!",0xa
str_syscall_len equ $-str_syscall

section .text
global _start
_start:

	mov eax,4
	mov ebx,1
	mov ecx,str_syscall
	mov edx,str_syscall_len
	
	int 0x80

	mov eax,1
	int 0x80

在这里插入图片描述

是不是发现不用库函数,直接进行系统调用很简单呢~嘻嘻,我们今天就到此为止了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值