首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ESI的使用不清楚

ESI的使用不清楚
EN

Stack Overflow用户
提问于 2016-04-28 12:28:36
回答 1查看 2.7K关注 0票数 1

我目前正在研究一些代码(X86)的组装和分解,在那里我尝试从它重新创建C代码。我至少知道寄存器和程序的基本知识。但在以下情况下,我无法理解ESI的用法:

代码语言:javascript
复制
mov esi, [esp+10h]
lea esi, [esi+0]

我不确定在这种情况下esp+10h是什么,但我不认为这很重要,因为它应该是一些随机的32位值,对吗?

据我所知,mov esi, [esp+10h]将从esp+10h中复制数据(实际值),并将其存储在ESI中。所以esi现在应该是某种数据。但之后,lea esi, [esi+0]来将esi+0 (即数据)解释为一个附加项,并将其写入esi中。

在我看到的堆栈溢出的另一个线程中,lea esi, [esi+0]实际上是一个nop(What is the meaning of lea 0x0(%esi),%esi)。这是有意义的,因为它不应该修改地址。但是当esi是关于使用情况的数据时,这是令人困惑的。所以我的C代码是这样的:

代码语言:javascript
复制
int esi = *(esp + 0x10); //move data from esp+10h to esi
int* esi = &esi;         //write the address of esi+0 to esi which is
                         //actually an int and not int*

因此,我的问题是,在寄存器级别上,数据和入口之间是否有任何区别,或者它是否被解释为相同,因为它看起来是相同的(32位寄存器)。我的另一个问题是,这段代码现在到底做了什么,ESI到底是什么?mov总是复制数据吗?lea总是复制一个地址吗?不管怎样,这不重要吗?

你可能已经猜到了,我很困惑,也许我只是想的太远了。请宽恕我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-28 16:30:34

CPU没有像高级语言那样的数据类型。对于CPU来说,所有的数据都只是位;将这些位解释为整数/位掩码/地址/浮点数只存在于程序员的脑海中。程序员有责任知道“这个32位值代表了一个字符数组的地址,所以我只应该用它做一些在这个上下文中有意义的事情”。但是如果你做了一些不太明智的事情,比如转移地址,机器就不会阻止你。

第一条指令接受esp寄存器中的值(通常包含堆栈顶部的地址),添加10h,从该地址获取32位值,并将其加载到esi寄存器中。这个地址上的值可能是一个局部变量或函数参数,它被加载到esi中以准备进一步的计算。

第二个指令接受esi寄存器中的值,添加0,并将该值加载到esi中。(注意,它不会从内存中提取任何东西,尽管指令的外观是“间接的”;这是lea指令的一个奇怪之处,它本质上计算一个地址,但随后不会取消它的引用。您可以认为它有点像C的一元&。)正如您说的,这是一个不操作;是的,在esi中有数据,但是它被“替换”了。

请注意,机器中只有一个esi寄存器,因此将其声明为两个不同变量的代码具有误导性。把esi看作是一个全局变量。

因为C确实有数据类型,为了在C中获得类似的效果,您必须在整个地方进行类型设置。我会用这样的方式表达代码:

代码语言:javascript
复制
int esi, esp;

esi = *(int *)(esp + 0x10);
esi = (int)&*(int *)esi; // does nothing

(您必须假设可以将整数转换为指针和返回,而不需要更改它们的值。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36914729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档