gpt4 book ai didi

c++ - 内联汇编 - cdecl 和准备堆栈

转载 作者:太空狗 更新时间:2023-10-29 11:46:32 25 4
gpt4 key购买 nike

我最近一直在尝试通过使用缓冲区和不同汇编运算符的 RAW 十六进制等价物在 C++ 中实现动态函数。为了说明一个简单的跳转:

byte * buffer = new buffer[5];
*buffer = '0xE9'; // Hex for jump
*(uint*)(buffer + 1) = 'address destination';

我没有汇编经验,但我知道足以创建非常简单的函数。现在我正在原始内存中创建 cdecl 函数。问题是,我不知道我想用 sub 将堆栈压入多少(用于内存)。我们以这个函数为例:

int MyTest(int x, int y) { return x + y; }

long TheTest(int x, int y)
{
return MyTest(x, 5);
}

08048a20 <_Z6TheTestii>:
_Z6TheTestii():
8048a20: 55 push %ebp
8048a21: 89 e5 mov %esp,%ebp
8048a23: 83 ec 18 sub $0x18,%esp
8048a26: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp)
8048a2d: 00
8048a2e: 8b 45 08 mov 0x8(%ebp),%eax
8048a31: 89 04 24 mov %eax,(%esp)
8048a34: e8 c2 ff ff ff call 80489fb <_Z6MyTestii>
8048a39: c9 leave
8048a3a: c3 ret

如您所见,首先是 C++ 代码,下面是“TheTest”函数的 ASM。人们可以立即注意到堆栈被压入 24 (0x18) 字节(如前所述,我没有使用汇编的经验,所以我可能没有使用正确的术语和/或完全正确)。这对我来说没有任何意义。当只使用 2 个不同的整数时,为什么需要 24 个字节?使用了变量“x”,它是 4 个字节,值“5”也使用了 4 个字节(记住它是 cdecl,因此调用函数负责处理与函数参数相关的内存)补24....

现在这是一个额外的示例,它让我真的对汇编输出感到疑惑:

int NewTest(int x, char val) { return x + val; }

long TheTest(int x, int y)
{
return NewTest(x, (char)6);
}

08048a3d <_Z6TheTestiiii>:
_Z6TheTestiiii():
8048a3d: 55 push %ebp
8048a3e: 89 e5 mov %esp,%ebp
8048a40: 83 ec 08 sub $0x8,%esp
8048a43: c7 44 24 04 06 00 00 movl $0x6,0x4(%esp)
8048a4a: 00
8048a4b: 8b 45 08 mov 0x8(%ebp),%eax
8048a4e: 89 04 24 mov %eax,(%esp)
8048a51: e8 ca ff ff ff call 8048a20 <_Z7NewTestic>
8048a56: c9 leave
8048a57: c3 ret

这里唯一的区别(值除外)是我使用“字符”(1 字节)而不是整数。如果我们再看一下汇编代码,它会将堆栈指针压入 8 个字节。这与前面的示例相差 16 个字节。作为一个地地道道的C++人,我都不知道这是怎么回事。如果有人能在这个问题上启发我,我将不胜感激!

注意:我在这里发帖而不是阅读 ASM 书籍的原因是因为我需要为这个一个函数使用汇编。所以我不想为了 40 行代码而读一整本书......

编辑:我也不关心平台依赖性,我关心 Linux 32 位 :)

最佳答案

TheTest 中创建的堆栈帧包含局部(自动)变量和函数参数,例如 MyTestNewTest,调用测试。框架由 TheTest 插入和弹出,因此只要它足够大以容纳它调用的函数的参数,大小就无关紧要。

您看到的编译器输出是编译器多次通过的结果。每个 channel 都可以执行转换和优化,以减少所需的帧大小;我怀疑在某些早期状态下,编译器需要 24 字节的帧,并且即使代码已优化也从未减少它。

您平台上编译器的 ABI 将建立一些您必须遵循的堆栈对齐规则,因此帧大小会四舍五入以满足这些要求。

这些函数使用帧指针%ebp%,尽管这并不是代码大小或性能的胜利;不过,这可能有助于调试。

关于c++ - 内联汇编 - cdecl 和准备堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10463960/

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