zoukankan      html  css  js  c++  java
  • 第10章 call和ret指令

    引言:

    call和ret都是转移指令,他们都修改ip,或同时修改cs和ip。

    他们经常被共同用来实现程序的设计

    10.1  ret和retf

    ret指令用栈中的数据,修改ip的内容,从而实现近转移。

    retf指令用栈中的数据,修改cs和ip的内容,从而实现远转移;

    可以看出,如果我们用汇编语法来解释ret和retf指令,则

    cpu执行ret指令时,相当于进行:

    pop  ip

    cpu执行retf指令时,相当于进行:

    pop  ip

    pop  cs

    10.2  call指令

    cpu执行call指令,进行两步操作:

    1)将当前的ip或cs和ip压入栈中;

    2)转移

    call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相同,下面的几个小节中,我们以给出转移目的地址的不同方法为主线,讲解call指令的主要应用格式

    10.3   依据位移进行转移的call指令

    call标号(将当前的ip压入栈后,转到标号处执行指令)

    cpu执行此种格式的call指令时,进行如下的操作:

    1)sp=sp-2

    2)ip=ip+16位位移

    call标号

    16位位移=标号处的地址--call指令后的第一个字节的地址;

    16位位移的范围为-32768~32767,用补码表示

    16位位移由编译程序在编译时算出。

    从上面的描述中,可以看出,如果我们用汇编语法来解释此种格式的call指令,则:

    cpu执行指令call标号时,相当于进行:

    push  ip

    jmp  near  ptr  标号

    10.4   转移的目的地址在指令中的call指令

    前面讲解的call指令,其对应的机器指令中并没有转移的目的地址,而是相对于当前ip的转移位移。

    指令call  far  ptr  标号  实现的是段间转移

    cpu执行call fat  ptr  标号这种格式的call指令时的操作:

    1)sp=sp-2

    ssx16+sp=cs

    sp=sp-2

    ssx16+sp=ip

    2)cs=标号所在的段地址

    ip=标号所在的偏移地址

    cpu执行指令call  far  ptr  标号时,相当于进行:

    push  cs

    push  ip

    jmp  far  ptr  标号

    10.5   转移地址在寄存器中的call指令

    指令格式:call  16位寄存器

    功能:

    sp=sp-2

    ss*16+sp=ip

    ip=(16位寄存器)

    汇编语法解释此种格式的call指令,cpu执行call16位reg时,相当于进行:

    push  ip

    jmp   16位寄存器

    10.6  转移地址在内存中的call指令

    转移地址在内存中的call指令有两种格式:

    1)call word   ptr  内存单元地址

    汇编语法解释:

    push  ip

    jmp  word   ptr  内存单元地址

    例如:

    mov   sp,10h

    mov ax,0123h

    mov ds:[0],ax

    call word ptr ds:[0]

    执行后,ip=0123h,sp=0eh

    2)call  dword  ptr  内存单元地址

    汇编语法解释:

    push  cs

    push   ip

    jmp   dword   ptr   内存单元地址

    例如:

    mov  sp,10h

    mov ax,0123h

    mov ds:[0],ax

    mov word ptr ds:[2],0

    call dword  ptr  ds:[0]

    执行后,cs=0,ip=0123h,sp=0ch

    10.7  call和ret的配合使用

    我们看一下call和ret如何配合使用来实现子程序的机制

    我们来看以下cpu执行这个程序的主要过程:

    1)cpu将call s指令的机器码读入,ip指向了call  s后的指令mov  bx, ax,然后cpu执行call  s指令,将当前的ip值(指令mov  bx,ax的偏移地址)压栈,并将ip的值改变为标号s处的偏移地址。

    2)cpu从标号s处开始执行指令,loop循环完毕,ax=8

    3)cpu将ret指令的机器码读入,ip指向了ret指令后的内存单元,然后cpu执行ret指令,从栈中弹出一个值(即call先前压入栈的mov  bx, ax指令的偏移地址)送入ip中。则cs:ip指向指令mov  bx ,ax

    4)cpu从mov  bx ,ax开始执行指令,直至完成。

    10.8  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*(dx*16+bx+si+8)结果的高16位

    例如:

    1)计算100*10

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

    mov  al,100

    mov  bl,10

    mul  bl

    结果ax=1000

    2)计算100*10000

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

    mov  ax,100

    mov bx,10000

    mul bx

    结果  ax=4240h,dx=000fh

    (f4240h=1000000)

    10.11批量数据的传递

    当参数过多时,如何实现参数传递?

    在这种时候,我们将批量数据放到内存中,然后将他们所在内存空间的首地址放在寄存器中,传递给需要的子程序。

    对于具有批量数据的返回结果,也可用同样的方法。

  • 相关阅读:
    tar命令详解
    保存GNOME桌面环境中声卡的音量设置
    SyntaxError: NonASCII character ‘\xe5′ in file
    Python小练习采集天气预报
    Debian编译内核教程
    Debian软件包依赖关系图
    mysql unauthenticated user原因分析以及解决方法
    Struts2 配置
    Map基本操作
    Iterator迭代器
  • 原文地址:https://www.cnblogs.com/fate-/p/12944446.html
Copyright © 2011-2022 走看看