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

news/2025/2/27 5:18:18
汇编程序中, 对数据访问时, 通常是这样的:

_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数据地址的错误引用造成程序错误.



http://www.niftyadmin.cn/n/3654623.html

相关文章

callee和caller的使用

callee callee是arguments对象中的一个方法,功能是引用arguments所在的函数。 案例: //命名函数 function fn(){console.log(arguments.callee)} fn() 结果如下: //ƒ fn(){console.log(arguments.callee)}//匿名函数 (function(){console.l…

高性能网络编程MailList 热点回顾 [1]

早在今年2月份, 鉴于国内服务器程序开发的同仁一直以来都没有一个固定的场所可以互相交流, 我在google group上建了一个有关高性能网络编程的maillist (加入的方法见这里), 现已经加入的600多名成员中, 所属领域较为广泛: 有从事网游服务器开发的, 有从事IM服务器开发的, 也有…

ES3常用数组方法

增删系列方法: push(元素1,元素2,…,元素n) 功能:往源数组的末端添加元素。 返回值:添加元素后,源数组的长度。 示例: var a [1] a.push(2,3,4) console.log(a) //(4) [1, 2, 3, …

左侧列表栏添加了一项内容

栏目名称是: "我所关注的与关注我的", 我会将通过technorati.com找到引用或连接我BLOG的blog通过挑选放在这里, 挑选的基本条件是:1.要保持一定的更新量, 如每周不少于一两篇新文, 让我知道你还在写blog;2.对我和其他朋友有一定阅读价值, 不管技术的或非技术的.

两步让对象变数组

在javascript中,数组也是对象类型,但是真正意义上的对象和数组还是有区别,一般的json对象是不具备数组的方法和属性的。 案例: //对象var arr {0 : javascript,1 : java,2 : node}// 数组var arr1 [javascript,java,node]分析:数…

只贴链接不说话: QQ的架构

很早之前, 我们在maillist里的讨论:http://groups.google.com/group/dev4server/browse_thread/thread/0d72668d11c4886b/#今天, 看到的在CSDN 论坛里的讨论:http://community.csdn.net/Expert/TopicView3.asp?id4825364

CSS如何让元素水平,竖直方向都居中?

第一种 原理&#xff1a;通过定位和调整matgin-top和margin-left的位置的方式调节。 <style type"text/css">.demo{width: 200px;height: 200px;background-color: skyblue;position: absolute;top:50%;left: 50%;margin-top: -100px;margin-left: -100px;}<…

孔乙己之一----this

本文作者:sodme本文出处:http://blog.csdn.net/sodme声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明信息. 谢谢.这是一个小问题, 孔乙己一把, 全当自娱. 今天在线上被问到一个问题, 描述如下:#include using nam…