鱼C论坛

 找回密码
 立即注册
查看: 483|回复: 6

汇编代码求解-3

[复制链接]
发表于 2023-7-13 15:33:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

                               
登录/注册后可看大图




问题:00401041  mov eax,[esp]  为啥不是  mov eax,[esp+4]?

          00401055 mov eax,[esp+4] 为啥不是  mov eax,[esp]?


        感觉这个两个地方代码有错误,求解答!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-13 15:34:21 | 显示全部楼层
汇编语言中的 [esp][esp+4] 涉及栈上数据的访问。在解释这两个指令之前,我们需要了解一些关于栈的基本知识。

栈是一种特殊的数据结构,遵循"先进后出"(LIFO)原则。在程序执行期间,栈用于保存函数调用的现场信息、局部变量以及其他重要数据。栈通过栈指针(SP)进行操作,通常在 x86 架构中使用 esp 寄存器作为栈指针。

对于 mov eax, [esp] 这条指令,它将从栈顶取出一个 DWORD(32 位数据)并将其存储到 eax 寄存器中。栈顶元素实际上是 [esp] 所指向的数据。由于栈是向下增长的,所以 esp 存储的是栈顶地址,而不是栈顶元素的地址。

现在来分析 mov eax, [esp+4]。这条指令将从相对于 esp 偏移 4 字节的位置处取出一个 DWORD,并将其存储到 eax 寄存器中。在典型情况下,函数调用会在栈上保存返回地址,然后是函数参数。因此,偏移 4 字节的位置通常是函数的第一个参数。

综上所述,不同的指令 mov eax, [esp]mov eax, [esp+4] 是针对栈上不同的数据进行访问。具体要使用哪个偏移取决于栈上存储的数据结构和处理逻辑的需求。

如果你对特定程序中的上下文有更多了解,例如在 mov eax, [esp]mov eax, [esp+4] 指令之前的指令序列或者对应的函数调用,那么可以提供更多信息以便更准确地解释这两个指令的用途。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-13 15:44:53 | 显示全部楼层
陶远航 发表于 2023-7-13 15:34
汇编语言中的 [esp] 和 [esp+4] 涉及栈上数据的访问。在解释这两个指令之前,我们需要了解一些关于栈的基本 ...

图片上 esp指向n2的地址  ,esp+4指向n1的地址,

argc?n1:n2+3       argc不为0,即执行n1,而n1的地址是[esp+4],

所以00401041应该是 mov eax,[esp+4]啊!难道书上错误了?
QQ图片20230713153952.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-13 16:57:41 | 显示全部楼层
对于问题1:为什么是`mov eax,[esp]`而不是`mov eax,[esp+4]`?

在汇编代码的00401041行,该指令`mov eax,[esp]`是将栈顶的值(位于[esp]的位置)存储到eax寄存器中。由于先前已经执行了一系列push操作,将所需的参数压入栈中,所以在这里直接使用`mov eax,[esp]`来获取函数参数argc的值。

对于问题2:为什么是`mov eax,[esp+4]`而不是`mov eax,[esp]`?

在汇编代码的00401055行,该指令`mov eax,[esp+4]`是将相对于栈顶偏移4字节的值(位于[esp+4]的位置)存储到eax寄存器中。这里是因为先前的call指令和push指令都将两个参数压入了栈中,然后再进行相应的操作。所以在这里使用`mov eax,[esp+4]`来获取第二个参数n1的值。

总结:

问题1和问题2中的代码都没有错误。在汇编代码中,栈是以LIFO(Last-In-First-Out)的方式组织的,`[esp]`表示栈顶的值,而`[esp+4]`表示相对于栈顶偏移4字节的值。因此,在不同的位置上,需要根据具体需求来选择对应的偏移。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-13 18:46:18 | 显示全部楼层
本帖最后由 HWitty 于 2023-7-13 18:47 编辑
sfqxx 发表于 2023-7-13 16:57
对于问题1:为什么是`mov eax,[esp]`而不是`mov eax,[esp+4]`?

在汇编代码的00401041行,该指令`mov ea ...


它是把argc的值和0比较,,等于0才跳转到00401055,才把【esp+4】也就是n1的值给eax,

问题是   argc?n1:n2+3   当argc==0时,表达式为假,要执行n2+3的嘛,这就对不上啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-14 09:30:54 | 显示全部楼层
sfqxx 发表于 2023-7-13 16:57
对于问题1:为什么是`mov eax,[esp]`而不是`mov eax,[esp+4]`?

在汇编代码的00401041行,该指令`mov ea ...

麻烦看一下,最新回复
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-14 12:26:13 | 显示全部楼层
HWitty 发表于 2023-7-13 18:46
它是把argc的值和0比较,,等于0才跳转到00401055,才把【esp+4】也就是n1的值给eax,

问题是   arg ...

在给定的汇编代码中,我们可以观察到该程序正在使用堆栈来操纵值并进行比较。让我们分析一下你问题中提到的具体指令。

1. `mov eax, [esp]`:这条指令将堆栈顶部的值(即存储在`[esp]`处的值)复制到`eax`寄存器中。在这种情况下,它用于获取`argc`的值。

2. `mov eax, [esp+4]`:这条指令将`[esp+4]`处的值复制到`eax`寄存器中,即获取堆栈上的第二个元素。这个值对应于C++源代码中的`n1`。

关于你对`argc ? n1 : n2+3`的困惑,让我们解释一下它是如何工作的:

- `argc`表示传递给程序的命令行参数的数量。
- 如果`argc`非零(true),程序将执行语句`n1`,因为`n1`是从输入中读取的第一个值。
- 如果`argc`为零(false),程序将执行语句`n2 + 3`,因为`n2`是从输入中读取的第二个值。

因此,根据条件(`?`)和`argc`的值,程序将相应地执行`n1`或`n2+3`。

如果您对此解释有任何疑问或问题,请提供更多上下文或进一步澄清您的问题。

求最佳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 14:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表