gpt4 book ai didi

汇编、栈上局部变量的算术运算

转载 作者:行者123 更新时间:2023-12-02 20:12:26 28 4
gpt4 key购买 nike

我最近一直在使用 Visual C++ 中的内联汇编,我想知道是否可以直接向堆栈上的局部变量添加值,例如:

push 5
add [esp], 7

这样做可以吗?我问这个问题是因为我在执行此操作时随机遇到了一些奇怪的问题(尽管大多数时候它工作正常),但是如果我通过寄存器,我永远不会遇到任何问题,如下所示:

push 5
mov eax, [esp]
add eax, 7
mov [esp], eax

最佳答案

正如 Vlad Krasnov 在对该问题的评论中所说,问题来自于编译器(和/或汇编器)不知道代码中参数的大小,如 add [esp], 7。例如,如果您编写 add [esp], eax,则不会出现此问题。

如果你是编译器,你会如何解释这条指令?系统会要求您将 7 添加到 ESP 指向的内存位置。但 7 和 [esp] 都没有指定加法的参数有多大。一个字节?两个字节?四个字节?如果这不是内联汇编(64 位代码中不允许),甚至 8 个字节也是可能的。

请注意,虽然 ESP 是 4 个字节,但它指向的内存位置可以是任意大小。立即数 7 也是如此,它可以容纳任意数量的字节。

正如 Vlad Krasnov 在评论中再次提到的,解决方案是显式指定操作数的大小。您可以查看您最喜欢的汇编器的文档,但在这种情况下,如果您想要 32 位加法,您可以编写 add DWORD PTR [esp], 7。这显然表明 [esp] 指向内存中的 DWORD(对于 MASM 来说是 32 位。)

另请注意,并非 x86 上的所有指令都支持其中包含立即值和内存地址的形式。对于每条指令,您可以检查“英特尔架构软件开发人员手册”,第 2 卷(指令集引用),以确保您尝试使用的指令确实存在!

而且,您应该始终检查编译器的汇编输出(因为您正在使用内联汇编),以确保编译器生成的代码实际上是您想要的。指示编译器生成汇编代码非常容易,而且可读性很好!

关于汇编、栈上局部变量的算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15181592/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com