当前位置:  开发笔记 > 编程语言 > 正文

x86指令是什么意思"call dword ptr ds:[00923030h]"?

如何解决《x86指令是什么意思"calldwordptrds:[00923030h]"?》经验,为你挑选了2个好方法。

以下x86汇编程序指令有何功能?

call dword ptr ds:[00923030h]

这是我怀疑的间接电话,但它究竟是如何计算通话的地址的呢?



1> Adam Rosenfi..:

[编辑]更新

每当你看到类似的内存操作数时ds:0x00923030,这就是一个段相对寻址模式.被参考的实际地址tp是相对于ds段寄存器的基地址的线性地址0x00923030 .

x86架构中的内存分段有点令人困惑,我认为Wikipedia在解释它方面做得很好.

基本上,86具有许多特殊寄存器:cs(代码段), ds(数据段), ,es,fs,gsss(堆栈段).每个存储器访问都与某个段寄存器相关联.通常,您不指定段寄存器,并且根据访问存储器的方式,使用默认段寄存器.例如,cs寄存器用于读取指令.

每个段寄存器都有一定的基址限制.基址确定线性地址0x00000000对应的物理地址,并且该限制确定该段的最大允许线性地址.例如,如果基址为0x00040000且限制为0x0000FFFF,则唯一有效的线性地址为0x00000000至0x0000FFFF,相应的物理地址为0x00040000至0x0004FFFF.

因此,被调用的子程序所驻留的物理地址由存储在ds段寄存器中的基地址加上0x00923030给出.但是我们还没有完成 - 指令中有这个词ptr.这增加了额外的间接级别,因此子例程的实际目标是存储在该位置的地址ds:0x00923030.

在AT&T语法中(由GNU汇编程序接受),指令将按如下方式编写:

lcall *ds:0x00923030

有关该指令的完整详细信息,请参阅80386参考手册.指令的这种特定变体是"CALL r/m16"(调用接近寄存器间接/存储器间接).



2> newgre..:

此特定操作码通过位于逻辑地址指向的位置的虚拟地址(此处为32位)进行调用ds:[00923030h].
逻辑地址由两个组件组成:

    在这种情况下,16位段选择器ds,它基本上是操作系统管理的(全局/本地)描述符表的索引.这样的选择器还保存给定段的访问权限信息,该访问权限信息在访问时被检查(当前权限级别,CPL)

    32位偏移
    然后计算最终地址如下:从选择器+偏移量取出的基地址

请注意,上面的计算表示线性地址,而不是物理地址(参见intel手册第3a卷,图2.2),然后通过4KB分页的标准机制进行转换,即地址由页面目录的索引,页面组成.表和所选页面的偏移量.但请记住,所有主流操作系统都使用所谓的平坦内存模式,这意味着所有段选择器都指向地址0x00000000,限制设置为0xFFFFFFFF,这就是为什么你可以在所有段之间进行转换并最终导致(容易)利用缓冲区溢出.

您给出的汇编程序指令很可能是通过可执行文件的导入地址表(请参阅这篇伟大的文章以获取更多详细信息)进行调用,即这不太可能是一个序数子例程调用.
像这样的代码是由编译器发出的,因为来自外部dll的导入函数的最终虚拟地址通常在编译时是不可知的(由于dll的重新定义).通过使用这样的调用构造,OS加载器可以通过逻辑地址在地址指针处插入正确的虚拟地址,并且编译器无需关心最终函数具有哪个地址.

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有