c - 为什么会发生字节溢出以及它们的作用是什么?

标签 c memory assembly x86 llvm

什么是字节溢出?

当我从 C 程序生成的 LLVM 中间表示中转储 x86 ASM 时,会出现大量溢出,通常为 4 字节大小。我无法弄清楚它们为什么会发生以及它们取得了什么成就。

他们似乎“切断”了堆栈的一部分,但以一种不同寻常的方式:

## this fragment comes from a C program right before a malloc() call to a struct.
## there are other spills in different circumstances in this same program, so it
## is not related exclusively to malloc()
...
sub ESP, 84
mov EAX, 60
mov DWORD PTR [ESP + 80], 0
mov DWORD PTR [ESP], 60
mov DWORD PTR [ESP + 60], EAX # 4-byte Spill
call malloc
mov ECX, 60
...

最佳答案

寄存器溢出就是当你的局部变量比寄存器多时发生的事情(这是一个类比 - 真正的意思是它们必须保存到内存中)。该指令正在保存 EAX 的值,可能是因为 EAX 被 malloc 破坏了,并且您没有另一个备用寄存器来保存它(无论出于何种原因,编译器都决定稍后在寄存器中需要常量 60)。

从表面上看,编译器当然可以省略 mov DWORD PTR [ESP + 60], EAX 而是重复 mov EAX, 60否则 mov EAX, DWORD PTR [ESP + 60] 或它使用的任何偏移量,因为此时 EAX 的保存值不能超过 60。但是,编译并不能保证完美。

还要记住,在 sub ESP, 84 之后,堆栈大小不会调整(当然,调用返回地址的调用指令除外)。以下说明使用 ESP 作为内存偏移量,而不是目标。

关于c - 为什么会发生字节溢出以及它们的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16453314/

相关文章:

OpenCL 缓冲区之间的指针

用C调用汇编代码,输出错误

编译器忽略 if 语句

c - 如何获取按长度排序的 C 代码函数列表?

c - 请问我能得到关于格式化的重点的提示吗?

c - 访问共享内存段时出现段错误

python - 庞大的图结构

c - scanf 不读取 mychars

c - 在调用 C 标准库函数之前是否应该备份寄存器?

c - 如何创建一个文本文件,在给定路径中该文件不存在