zoukankan      html  css  js  c++  java
  • Call指令和Ret指令讲解03 零基础入门学习汇编语言50

    第十章:Call指令和Ret指令讲解03

     

    让编程改变世界

    Change the world by program


     

    call指令和ret指令的配合使用2

     

    我们看一下程序的主要执行过程:

    (1)前三条指令执行后,栈的情况如下: [caption id="attachment_372" align="aligncenter" width="300"] call指令和ret指令的配合使用[/caption]   (2)call 指令读入后,(IP) =000EH,CPU指令缓冲器中的代码为 B8 05 00 CPU执行B8 05 00,首先,栈中的情况变为: [caption id="attachment_373" align="aligncenter" width="300"] call指令和ret指令的配合使用[/caption]   然后,(IP)=(IP)+0005=0013H。 (3)CPU从cs:0013H处(即标号s处)开始执行。 (4)ret指令读入后:(IP)=0016H,CPU指令缓冲器中的代码为 C3; 当CPU执行C3,相当于进行pop IP,执行后,栈中的情况为: [caption id="attachment_374" align="aligncenter" width="300"] call指令和ret指令的配合使用[/caption]   (IP)=000EH; (5)CPU回到 cs:000EH处(即call指令后面的指令处)继续执行。   从上面的讨论中我们发现,可以写一个具有一定功能的程序段,我们称其为子程序,在需要的时候,用call指令转去执行。   可是执行完子程序后,如何让CPU接着call指令向下执行? 没错,答案就是ret。   call指令后面的指令的地址将存储在栈中,所以可以在子程序的后面使用 ret 指令,用栈中的数据设置IP的值,从而转到 call 指令后面的代码处继续执行。 这样,我们可以利用call和ret来实现子程序的机制。   我们来看一段用C写的程序源代码下载)  

    子程序的框架

    [caption id="attachment_375" align="aligncenter" width="260"] 子程序框架[/caption]  

    mul指令

    因下面要用到,我们介绍一下mul指令,mul是乘法指令,使用 mul 做乘法的时候:  

    (1)相乘的两个数:要么都是8位,要么都是16位。

    8位: AL中和 8位寄存器或内存字节单元中;

    16位: AX中和 16 位寄存器或内存字单元中。

     

    (2)结果

    8位:AX中;

    16位:DX(高位)和AX(低位)中。

     

    格式如下:

    mul reg

    mul 内存单元

      内存单元可以用不同的寻址方式给出,比如:

    mul byte ptr ds:[0]

    含义为:

    (ax)=(al)*((ds)*16+0);

     

    mul word ptr [bx+si+8]

    含义为:

    (ax)=(al)*((ds)*16+(bx)+(si)+8)结果的低16位;

    (dx)=(al)*((ds)*16+(bx)+(si)+8)结果的高16位;

     

    (1)计算100*10

    100和10小于255,可以做8位乘法,程序如下:

    mov al,100

    mov bl,10

    mul bl

    结果: (ax)=1000(03E8H)  

    (2)计算100*10000

    100小于255,可10000大于255,所以必须做16位乘法,程序如下:

    mov ax,100

    mov bx,10000

    mul bx

    结果: (ax)=4240H,(dx)=000FH(F4240H=1000000)  

    模块化程序设计

      从上面我们看到 ,call 与 ret 指令共同支持了汇编语言编程中的模块化设计。在实际编程中,程序的模块化是必不可少的。 因为现实的问题比较复杂,对现实问题进行分析时,把它转化成为相互联系、不同层次的子问题,是必须的解决方法。 而call和ret 指令对这种分析方法提供了程序实现上的支持。利用 call和ret指令,我们可以用简洁的方法,实现多个互相联系、功能独立的子程序来解决一个复杂的问题。   下面的内容中,我们来看一下子程序设计中的相关问题和解决方法。 子程序一般都要根据提供的参数处理一定的事务,处理后,将结果(返回值)提供给调用者。 其实,我们讨论参数和返回值传递的问题,实际上就是在探讨,应该如何存储子程序需要的参数和产生的返回值。  

    请思考

    我们设计一个子程序,可以根据提供的N,来计算N的3次方。 这里有两个问题:

    (1)我们将参数N存储在什么地方?

    (2)计算得到的数值,我们存储在什么地方?

     

    参数和结果传递的问题

    很显然,我们可以用寄存器来存储,可以将参数放到 bx 中 因为子程序中要计算 N×N×N ,可以使用多个 mul 指令,为了方便,可将结果放到 dx 和 ax中。   子程序: 说明:计算N的3次方 参数: (bx)=N 结果: (dx:ax)=N^3 cube:

    mov ax,bx

    mul bx

    mul bx

    ret

    注意,我们在编程的时候要注意良好的风格,对于程序应有详细的注释。子程序的注释信息应该包含对子程序的功能、参数和结果的说明。 因为今天写的子程序,以后可能还会用到;自己写的子程序,也很可能要给别人使用,所以一定要有全面的说明。   用寄存器来存储参数和结果是最常使用的方法。对于存放参数的寄存器和存放结果的寄存器,调用者和子程序的读写操作恰恰相反: 调用者将参数送入参数寄存器,从结果寄存器中取到返回值; 子程序从参数寄存器中取到参数,将返回值送入结果寄存器。  

    编程:计算data段中第一组数据的 3 次方,结果保存在后面一组dword单元中。

    data segment

    dw 1,2,3,4,5,6,7,8

    dd 0,0,0,0,0,0,0,0

    data ends 请课后先思考一下……尽管书中有答案…… [buy] 获得所有教学视频、课件、源代码等资源打包 [/buy] [Downlink href='http://kuai.xunlei.com/d/LBUNXPIUQFTP']视频下载[/Downlink]
  • 相关阅读:
    关于相机权限
    JDBC插入中文出现乱码问题
    记一次Java代码的部署
    Java-final关键字
    Java枚举使用详解
    临时表
    Oracle 11g 建表 表名大小写问题
    ORA-04021等待锁定对象时超时
    Oracle 查询时间差几天
    NVL()
  • 原文地址:https://www.cnblogs.com/LoveFishC/p/3846037.html
Copyright © 2011-2022 走看看