`
阿尔萨斯
  • 浏览: 4173157 次
社区版块
存档分类
最新评论

对标号地址的另一种相对寻址方式

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
汇编程序中, 对数据访问时, 通常是这样的:

_asm{
...
DATA_LABLE:
_emit 0x87
_emit 0xa0
_emit 0x49
_emit 0x90
...

mov ebx, dword ptr [DATA_LABLE]
...
}

其中, 当程序编译之后, mov指令中的DATA_LABLE标号地址会被转成一个绝对地址. 而有时绝对地址这一点可能会对这样一种需求带来障碍: 我们希望自己写的汇编代码不管被放在哪块地址空间中都是能正常运行的, 就象我们写高级语言中的那些函数一样, 函数位置可以被随意放置, 丝毫不会影响函数本身的功能使用. 当然, 不得不指出的是, 尽管要求的是同样功能, 但汇编与高级语言之间在这方面的实现却相去甚远. 高级语言的函数在最终被编译之后, 其函数地址也是固定的绝对地址, 而我们所想要用汇编实现的才是真正的"可被任意放置"的二进制执行块.

借用call指令, 可以实现运行期标号地址的相对寻址, 大致的思路如下:

_asm{
...
call FUNC_START
FUNC_START:
pop ebx
sub ebx, offset FUNC_START
mov [ebp-xx], ebx
...

DATA_LABLE:
_emit 0x87
_emit 0xa0
_emit 0x49
_emit 0x90

...
mov eax, [ebp-xx]
mov ebx, dword ptr [DATA_LABLE+eax]
...

}

步骤是这样的:

1.首先, 在汇编功能块或函数首部, 使用以下语句取得运行期地址与编译地址的修正差值.
call FUNC_START
FUNC_START:
pop ebx
sub ebx, offset FUNC_START
mov [ebp-xx], ebx

略作解释: call 函数会将eip寄存器压入堆栈, 之后用"pop ebp"是将eip值赋给ebp, 而eip表示的是"下一条语句的地址", 在这里, 当程序运行到"call FUNC_START"时, 它表示的是以标号"FUNC_START:"开始的"pop ebx"指令起始地址. 而另一方面, sub指令中的"offset FUNC_START", 在编译时, offset会被转成一个绝对地址. 这样,通过sub操作, 就获得了此段代码在编译期和运行期关于指令地址的修正值. 下面的这句: "mov [ebp-xx], ebx", 实际上只是锦上添花, 它把这个值保存在了某一个自定义的函数局部变量空间内, 以备后续语句方便引用.

2.相应的, 对标号数据的引用就变成这样的两句:
mov eax, [ebp-xx]
mov ebx, dword ptr [DATA_LABLE+eax]

对于汇编函数中的此类代码进行这样的处理后, 此段二进制执行块就可以被放置在任意地方而不致因为对DATA_LABLE数据地址的错误引用造成程序错误.


分享到:
评论

相关推荐

    完整详细的汇编语言实验报告

    完整详细的汇编实验报告 ...熟悉和掌握7种不同的操作数寻址方式的使用方法。 (1)多数位的算术运算、移位操作、字符串操作等程序的设计 (2)学习使用分支与循环等基本编程方法 (3)熟练使用Debug。

    c#获得mac地址硬盘卷标号源代码

    rt c#获得mac地址硬盘卷标号的源代码 分享给大家互相学习

    单片机系统的设计与制作.doc

    特点:位寻址是直接寻址方式的一种,其特点是对8位二进制数中的某一位的地址进 行操作。 寻址范围:片内RAM低128B中位寻址区、部分SFR(其中有83位可以位寻址)。 可位寻址的位地址的表示形式如下: (1)直接使用...

    汇编语言教程

     3.7 相对基址加变址寻址方式  3.8 32位地址的寻址方式  3.9 操作数寻址方式的小结  3.10 习题 第4章 标识符和表达式  4.1 标识符  4.2 简单内存变量的定义  1 内存变量定义的一般形式  2 字节变量  3 ...

    dij 标号校正算法

    dij 最短路径的算法,存在一个弊端。 那就是它所处理的图的权值必须为正,为了校正这个缺点,后来也提出很多算法。 其中 标号校正算法 是 比较好的一种算法。 本文章介绍了标号校正算法的介绍,和推理~~

    电气直流二次回路标号详解

    本文主要对电气直流二次回路标号进行了详解,下面一起来学习一下

    微机接口及应用教程 微型计算机

    3.1.7 8086的寻址方式--基址加变址相对寻址 3.1.8 8086的寻址方式--输入/输出端口寻址 §3.2 8086的指令系统 3.2.1 通用数据传送指令 3.2.2 累加器专用传送指令 3.2.3 地址传送指令 3.2.4 标志传送指令 ...

    变压器连接组别标号的简易判别方法

    1变压器联结方式三相变压器是电力系统中的重要电气设备之一。在安装工程中,若变压器的联结方式不正确,不仅不能正常地向设备供电,还有可能危害设备甚至电网。因此三相变压器的联结标号正确判断对其正常运行极其重要。...

    混凝土标号

    混凝土标号描述,混凝土标号描述,混凝土标号描述,混凝土标号描述,混凝土标号描述,混凝土标号描述,

    汇编实验报告

    1、练习逻辑运算指令、比较指令和条件转移指令的功能、用法以及与标志位的关系和可用的寻址方式 2、用地址表法,完成下面要求的多分支程序的设计。根据MODE单元中的模式字(0-7)分别转向L0-L7标号处执行。L0-L7处...

    arm汇编指令集大全

    注意存储在跳转指令中的实际值是相对当前 PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址) 。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 ...

    梁泽宇:标号法——顺序维护的有力工具.pdf

    标号法(labeling method)寻找最短路线问题的最优方案的一个有效方法。采取顺加取大的方法。 基本步骤为: 1.先标出离起点最近的一段,将距离数字分别写在该段线终点上方的方格内. 2.在标下一段时,正要标号的某点到...

    单片机程序设计

    难点:寻址方式,控制转移指令中相对地址计算,堆栈操作,以及简单汇编程序阅读。 3、程序设计基本概念: (1)标号、操作码、操作数、注解; (2)伪指令:ORG、DB、DW、EQU; (3)程序状态字PSW。 4、简单程序...

    AD10_批量修改网络标号

    在使用AD10设计原理图时,当原理图中重复的部分比较多,需要统一修改各部分网络标号时,这个文档还是比较有用的。

    prote_dxp2004原理图新增器件的标号处理

    dxp2004中原理图中新增器件如何快捷进行重新标号?

    JAVA获取计算机硬盘序列号、分区卷标号、MAC地址、IP地址、计算机名称

    该jar工具包是通过DiskID.dll获取计算机硬盘序列号、分区卷标号、MAC地址、IP地址、计算机名称等的信息,获取内容如下: 计算机名称:201709071714 硬盘序列号:183534442995 C分区卷标号:29F513CB MAC地址:F0-A9-59-...

    标号法求最大流代码C++

    /*标号法求最大流代码*/ #include using namespace std; int lt[21][2]; int g[21][21][2]; int n,s,t,i,j,m,x,a,ma; bool f; int main(){ freopen("1.txt","r",stdin); int d; memset(lt,0,sizeof(lt)); memset...

    PCB 封装库及元器件标号的设计标准

    PCB 封装库及元器件标号的设计标准

    最大流的标号法ppt与代码(c++)

    最大流的标号法ppt与代码(c++源程序) 下别人滴的东西都比较贵 中国不打折

    二值图像连通域标号程序

    对二值图像连通域进行标号,可以选择四连通还是八连通

Global site tag (gtag.js) - Google Analytics