(十)汇编语言——CALL和RET指令
创始人
2024-05-13 00:27:53
0

(十)汇编语言——CALL和RET指令

文章目录

  • (十)汇编语言——CALL和RET指令
    • CALL指令
      • 功能
        • 寄存器
        • 内存
      • 段间转移
    • 返回指令
      • ret
      • retf
    • 实例
    • MUL指令
    • 模块化程序设计
      • 寄存器
      • 内存单元
    • 寄存器冲突问题
      • 方法

相信大家肯定在C语言里面接触过函数这个概念,或者是一些高级语言里面的方法,那么汇编语言有没有这样类似的概念呢,答案是当然的,接下来就让我们来介绍一下汇编的模块化程序设计。

CALL指令

这个CALL指令呢,我们是第一次接触,它主要的作用就是调用子程序,实质上就是进行流程转移,而且实现转移的方法和jmp指令的原理相似。使用的格式就是call 标号,这个就类似于,把当前位置保存起来,去执行其他地方的代码,执行完了之后再回到原处去执行。就类似于我们的中断。

功能

首先将当前的IP压入栈中,然后转移到标号处执行指令。相当于下面的语句。实现的是段间转移,如果我们要实现段内转移呢?我们继续讲解。

  1. (sp)=(sp)–2
  2. ((ss)*16+(sp))=(IP)
  3. (IP)=(IP)+16位位移
push IP
jmp near ptr 标号

寄存器

而如果转移地址在寄存器里面的话,就有一点不一样了,但是和我们之前介绍的 jmp 指令类似的,我们具体看看吧!就相当于下面的语句。

push IP
jmp 16位寄存器

内存

转移地址在内存中的call指令其实也是类似的,我们给出相应的语句,相信大家可以很清楚的理解到。

;call word ptr 内存单元地址
push IP
jmp word ptr 内存单元地址;calld word ptr 内存单元地址
push CS
push IP
jmp dword ptr 内存单元地址

段间转移

我们如果想要实现段间转移的话,使用的指令就是call far ptr 标号,这个时候,我们就会把CS和IP同时入栈保存起来。具体步骤如下所示:

  • (sp)=(sp)–2
  • ((ss)×16+(sp))=(CS)
  • (sp)=(sp)–2
  • ((ss)×16+(sp))=(IP)
  • (CS)=标号所在的段地址
  • (IP)=标号所在的偏移地址
push CS
push IP
jmp far ptr 标号

“call 标号”类似”jmp near ptr 标号”,对应的机器指令中为相对于当前IP的转移位移,而不是转移的目的地址,实现段内转移。而指令“call far ptr 标号”实现的是段间转移!

返回指令

我们这里主要介绍ret指令和retf指令。

ret

用栈中的数据,修改IP的内容,从而实现近转移,相当于 pop IP。

retf

用栈中的数据,修改CS和IP的内容,从而实现远转移;

实例

这个程序就是计算一下ax的平方,但是值得注意的就是,这里我们用到了栈段,因为我们的call 指令和ret指令需要入栈和出栈操作。

assume cs:code, ss:stack
stack segmentdb 8 dup(0)db 8 dup(0)
stack ends
code segmentstart :mov ax, stackmov ss,axmov sp,16mov ax,1000call smov ax, 4c00hint 21hs:add ax,axretcode ends
end start

MUL指令

mul指令就是我们的乘法指令,我们之前介绍过除法div指令,我们来简单回顾一下。

被除数AXDX和AX
除数8位内存或寄存器16位内存或寄存器
ALAX
余数AHDX

而接下来我们介绍的乘法指令与这个类似,我们来看看吧!

被乘数ALAX
除数8位内存或寄存器16位内存或寄存器
结果AXDX(高位)和AX(低位)

我们来看一个例子吧!计算100乘10和100乘10000。

;100*10
mov al,100
mov bl,10
mul bl;100*10000
mov ax,100
mov bx,10000
mul bx

模块化程序设计

我们知道,在程序设计中,模块化设计是十分重要的,那么,在汇编语言中有没有这要的设计呢?聪明的小伙伴们应该想到了,调用我们刚刚介绍的CALL 指令和RET指令即可。但是呢,需要我们去解决两个问题,那就是参数和返回值的问题,我们来看一下这两个问题我们如何来解决。

在这之前,我们来看一个问题,就是根据提供的N,计算N的3次方。我们可以考虑用循环去做,但是我们现在选择使用模块化程序设计的方法去解决,具体解决办法如下:

寄存器

把数据存储到寄存器里面是一个解决办法,我们来看看具体的操作。

  1. 首先把参数放到 bx 中,即(bx)=N;
  2. 然后子程序中用多个mul指令计算N3;
  3. 最后将结果放到dx和ax中:(dx:ax)=N3
assume cs:code
data segmentdw 1,2,3,4,5,6,7,8dd 0,0,0,0,0,0,0,0
data endscode segment
start:mov ax,datamov ds,axmov si,0     ;指向第一组单词mov di,16    ;指向第二组单词mov cx,8s:mov bx,[si]call cubemov [di],axmov [di].2,dxadd si,2add di,4loop s        ;循环处理mov ax,4c00hint 21hcube:mov ax,bxmul bxmul bxretcode ends
end start

这样处理当然是没有问题的,但是会面临一个问题,就是我们的寄存器只有那么多,如果需要传递的东西比较多,寄存器不够用了怎么办,确实这是我们会遇到的问题。既然寄存器比较少,我们就换一个方法,使用内存单元去传递信息。

内存单元

为了避免寄存器不够的尴尬,于是我们现在使用内存单元去传递数据。我们的做法就是先将批量数据放到内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序。对于具有批量数据的返回结果,也可用同样的方法。

比如我们看这个例子,将data段中的字符串转化为大写。

data segmentdb 'conversation'
data ends

我们来看一下具体的代码段怎么去写。

code segment
start:mov ax,datamov ds,axmov si,0mov cx,12;循环次数call capitalmov ax,4c00hint 21h
capital: and byte ptr [si],11011111b;变大写inc siloop capitalret
code ends

目前这样基本上是没有什么问题了。但是我们还要介绍另外一种方法,那就是通过我们的栈来实现传递参数。

接下来我们就使用栈来进行参数传递,主要的原理就是由调用者将需要传递给子程序的参数压入栈中,子程序从栈中取得参数。同样的,我们介绍一个例子,那就是计算(a–b)3,a、b为word型数据。我们来看一下代码段部分。

code segment
start:mov ax,1push axmov ax,3push ax;首先将一些数据入栈call difcube;调用子程序mov ax,4c00hint 21hdifcube:push bp;先在栈中保存BP的值mov bp,spmov ax,[bp+4]sub ax,[bp+6]mov bp,axmul bpmul bp;获得参数并计算,返回到AX中pop bp;恢复之前的BP值ret 4;放弃入栈的参数
code ends

好啦,这就是关于用栈来传递参数的方法,我们就介绍到这。

寄存器冲突问题

接下来我们将来解决有关寄存器冲突的问题,具体来说就是避免在子程序里面使用的寄存器与主程序里面使用的寄存器冲突了,导致程序无法运行。好啦,接下来我们就会来介绍如何解决这个问题。给大家一个提示,那就是使用我们经常使用的栈来保存数据。

方法

前面说了,我们是使用栈去解决这个问题,那么就让我们来卡看具体如何使用吧。

子程序开始:

  1. 子程序中使用的寄存器入栈
  2. 子程序内容
  3. 子程序使用的寄存器出栈
  4. 返回(ret、retf)
capital:push cxpush si
change:mov cl,[si]mov ch,0jcxz okand byte ptr [si],11011111binc sijmp short change
ok:pop sipop cxret

大家看这个地方,原理就是用栈先去保存数据,然后在程序结束的时候再把原来的数据出栈。
子程序中使用的寄存器入栈
2. 子程序内容
3. 子程序使用的寄存器出栈
4. 返回(ret、retf)

capital:push cxpush si
change:mov cl,[si]mov ch,0jcxz okand byte ptr [si],11011111binc sijmp short change
ok:pop sipop cxret

大家看这个地方,原理就是用栈先去保存数据,然后在程序结束的时候再把原来的数据出栈。

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...