zoukankan      html  css  js  c++  java
  • 8086汇编之 CALL 和 RET指令

    Ret 和 call 也是转移指令,可是他们跟jmp不同的是,这两个转移指令都跟栈有关系。

    <1> ret

    用栈中的数据改动IP的地址,从而实现近转移

    ( ip ) = ( (ss)*16+ sp )

    ( sp ) =( sp ) + 2

    相当于pop ip

    <2>retf

    用栈中的数据来改动CS以及IP的值,实现段间转移

    ( ip ) = ( (ss)*16+ sp )

    ( sp ) =( sp ) + 2

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

    ( sp ) =( sp ) + 2

    相当于

    Pop ip

    Pop cs

    <3> call xxx(行号)

    先把当前IP压栈,然后跳转,相当于实现近转移

    ( sp ) = ( sp ) – 2

    ( (ss)*16+ sp ) = ( ip )

    ( ip ) = ( ip ) + 16位位移

    相当于:

    Push ip

    Jmp near ptr xxx(行号)

    <4>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 xxx

    <5> call reg(16bit)

    跳转到16位寄存器上中存储的地址

    ( sp ) = (sp) – 2

    ( (SS)*16 + (sp) ) = (IP)

    (IP) = ( 16bit Reg )

    相当于:

    Push IP

    Jmp 16bit Reg

    <6> call word ptr 内存单元地址

    相当于

    Push IP

    Jmp word ptr 内存单元地址

    如:call word ptr ds:[0]

    <7> call dword ptr 内存单元地址

    相当于

    Push cs

    Push ip

    Jmp dword ptr 内存单元地址

    比如:jmp dword ptr DS:[0];

    <8>寄存器的冲突问题

    主程序调用子程序段的时候,可能子程序会用到主程序中使用的寄存器的值。程序在设计的时候不可能做到不让子程序使用主程序的寄存器,由于两者是相互独立的。你永远不会还有一个会做什么。所以在子程序中採取不使用主程序中调用的寄存器的做法是不可行的。

    解决方法:

    把寄存器用到的东西,保存到堆栈里面。子程序调用完成。再将堆栈保存的东西弹出。

  • 相关阅读:
    代理工具介绍
    Cookie 相关
    在JavaScript 使用命名空间
    oracle rank()用法
    sql update 特殊用法
    Repeat 嵌套绑定
    .net 中隐式事务和显示事务的用法
    为站点添加迅雷下载和快车下载
    缺少MSVCR71.DLL解决方式
    关于AppFabric Caching的学习摘录
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7295724.html
Copyright © 2011-2022 走看看