用汇编实现类似于C语言中的printf函数--学习笔记

以下内容只是本人的一些学习心得,如有谬误,希望诸位大神不吝赐教,菜鸟在此拜过各位大神。

这几天刚刚学了call和ret指令,call指令和ret指令是用来实现程序的跳转的,汇编程序中,主程序和子程序之间实现的跳转,是通过对cs和ip寄存器的值进行压栈或出栈实现的,本章中,我们的目标是实现类似于c语言中的printf函数的功能,不过在开始前,我们先来总结一下call和ret指令。

我们使用“()”将寄存器括起来的形式,表示该寄存器存储的值,比如(IP)表示偏移地址寄存器存储的值。

一、ret和retf指令:

1、ret指令用栈中的数据,修改ip的内容,实现近转移,下面是执行操作:

(1)(IP) = ((ss)*16 + (sp))

(2)  (sp) = (sp) + 2

其实质等同于:pop IP

2、retf指令用栈中的数据,修改ip寄存器的内容,实现远转移,下面是执行操作:

(1)  (IP) = ((ss)*16+(sp))

(2)  (sp)= (sp)+2

(3)  (cs)=((ss)*16+(sp))

(4)   (sp)= (sp)+2

其实质等同于:pop IP

    pop CS

二、call指令(注意:call指令不能实现段内短转移)

1、这里要对跳转指令进行必要的说明,所谓的跳转指令就是指jmp指令,下面我们来对jmp指令进行简要的说明:




如上图所示,囊括了jmp指令的大多数情况。

要了解以上列举的一系列内容,我们首先要知道jmp偏移位移的计算公式,什么是偏移位移,就是指IP寄存器值要加上的数值,就是偏移位移,计算公式如下图所示:




上图中的s和s0就是标号,现在我们就以jmp s0 和jmp s来进行说明,这两条指令都是段内短转移,短转移就是修改ip的值,短转移的修改范围为-128~127,也就是说以当前的jmp指令为基准,ip可以向后退128个字节或向前进127个字节,这个ip偏移位移是如何计算出来的呢,其实就是:

标号处地址-jmp指令后的第一个字节的偏移地址,比如mov bx,3(jmp s0后的第一条指令)的偏移地址为0001,而标号s0处的地址为0006,那么此时的偏移位移就是6-3=3,就是这么简单,注意,这里进行的是通过偏移位移进行跳转,而非通过目标地址进行跳转,这样做的好处是可以使程序更加灵活。

现在我们以jmp short 标号为例,进行一些简要的概括:

(1)jmp short 标号  -》(IP) = (IP) + 8位位移

(2)8位位移=标号处地址-jmp指令后的第一个字节的偏移地址

(3)short指令知名此处的位移为8位位移

(4)8位位移的范围为-128~127,用补码表示(这里的空间容量正好为2^8)

(5)8位位移由编译器在程序编译时算出。

由此可以类推jmp near ptr + 标号指令,这里near指的是jmp实现段内近转移,near表示ip的范围为-32768~32767,其他内容和jmp short 标号一致。


接下来我们来看看jmp +

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值