问题标签 [stack-pointer]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 汇编代码转储中 ECX 堆栈寄存器的功能
我可以使用编译这个程序gcc -m32 -fno-stack-protector -z execstack -fno-pie -no-pie -g -o vuln vuln.c
在使用调试器反汇编主要功能时,我将其作为输出:
GCC 版本:6.5.0
操作系统:Ubuntu 16.04
GDB 版本:7.11.1
我所指的教程显示了这个汇编代码:
我有以下问题:
如何获得教程中提到的完全相同的汇编代码转储?
输出的差异似乎是因为ecx
寄存器。该寄存器有什么作用,为什么它不是教程汇编代码的一部分?在 main 函数中,我构造了大小为十六进制的
缓冲区数组,这就是为什么教程的汇编代码是从 esp 寄存器中减去的原因,但我的汇编代码是减去十进制的。我无法理解这一点。500
1f4
1f4
204
516
编辑:如评论中所述,如果我添加-mpreferred-stack-boundary=2
到编译器标志,那么我会得到与教程相同的汇编代码。为什么?
stack - 如何在堆栈中编写推送和弹出函数?在 C 中
教授要求编写一个堆栈,然后在 C 中定义 push 和 pop 的函数。提示是使用堆栈指针和数组,但似乎我不能正确地做到这一点(我不明白我认为的教训) . 你能帮我整理一下吗?
windows - Child-EBP 与 Child-SP
在跟进一些windbg教程时,我注意到一些使用k
命令的调用堆栈采用这种格式,特别是我的
而像CodeProject这样的其他在线资源有k
命令以这种格式吐出信息
我对为什么我的输出和他们的输出之间存在差异以及这真正意味着什么感到困惑。
assembly - 引导加载程序启动时读取堆栈是否安全?
背景
我正在尝试制作一个适用于两种架构的引导加载程序:x86 和 PDP-11。主操作系统是为兼容 PDP-11 的机器编写的,但是从 x86 引导也应该可以工作,启动一个模拟器。
AFAIK,x86 将第一个磁盘扇区加载到0x7c00
并跳转到那里,如果最后两个字节是0x55 0xaa
. 相反,PDP-11 兼容机器将第一个扇区加载到0o20000
(八进制)并在第一个命令是NOP
并且最后两个字节是时执行它0xaa 0x55
。但是,由于某些硬件细节,加载的数据实际上是反转的——例如,x86 会读取0x12
的地方,另一台机器会读取0xed
. 在这种情况下,这在某种程度上是一个功能,因为如果我制作最后两个字节0x55 0xaa
,它们将适用于两台机器。
总之,PDP-11 兼容机器需要前两个字节来包含NOP
命令,即0o000240
,或0x00a0
。数据是反转的,所以 x86 实际上会读取0xff5f
。
问题
0x5f
是 x86 中的真实命令。不幸的是,它是pop di
。AFAIK,两者sp
和ss
值都没有指定,所以这个命令读取谁知道什么。
我的问题是:
- 在实践中,我可以假设它们要么指向有效堆栈,要么都设置为某个占位符,例如
0x0000:0x0000
或0xffff:0xffff
? - 可能
ss:sp
指向不安全读取的内存映射硬件寄存器?如果是的话,如果我阅读它们会发生什么更糟糕的事情?我不想意外杀死笔记本电脑。 - 可能
ss:sp
指向不可用的内存,即可能pop di
触发总线错误?如果是,BIOS 将如何从中恢复,即它会重新启动、显示消息或执行其他操作吗?
stack - 使用按位运算符确保堆栈指针对齐
假设我想8 bytes
在堆栈上保留,并且我还想确保当前stack pointer
是 8 字节对齐的。我已经看到了一些使用此逻辑确保电流sp
为 8 字节对齐的代码:
他们AND
用他们要在堆栈上保留的数量(当然是负数)。
这个逻辑是如何工作的?
assembly - 在自定义机器上运行 GCC 编译代码。在程序集中找不到 sp 初始化
我在尝试在我的自定义 rv32I 机器上运行 gcc 编译代码时正在经历 .lst。我找不到 sp 的初始值
gcc - 我应该如何让 gcc 在进入函数的途中将堆栈指针重新对齐到 16 字节边界?
我正在尝试使用 mingw64 让现有的 JIT 在 Windows x86_64 上运行。
当 JIT 回调到预编译代码并且该代码调用 Windows API 时,我遇到了段错误,因为movaps
在调用 Windows API 实现中的对齐移动指令时,调用的%rsp
不是 16 的倍数,即堆栈未对齐一个 16 字节的边界。
在我期望的快速解决方法中,我想我会让 gcc 在进入由 JIT 代码调用的预编译函数并最终调用 Windows API 函数的途中强制重新对齐堆栈。
该force_align_arg_pointer
属性的 gcc 文档:
在 x86 目标上,该
force_align_arg_pointer
属性可以应用于单个函数定义,生成备用序言和尾声,必要时重新对齐运行时堆栈。这支持将使用 4 字节对齐堆栈运行的旧代码与保留 16 字节堆栈以实现 SSE 兼容性的现代代码混合。
但是,添加__attribute__((force_align_arg_pointer))
到函数说明符对输出程序集没有影响。
我也试过-mpreferred-stack-boundary=4
,它明确要求2**4 == 16
所有功能对齐:
-mpreferred-stack-boundary=num
尝试保持堆栈边界与 2 提升到num字节边界对齐。
这也没有效果。
事实上,我发现影响输出程序集的第一件事是-mpreferred-stack-boundary=3
(它应该保持堆栈与 8 字节边界对齐)。
这导致了这种差异:
奇怪的是,这实际上是放入andq $-16, %rsp
(将堆栈指针对齐为 16 的倍数),尽管我们说更喜欢 8 字节对齐。
我对这些选项或它们适用的案例有什么误解?
gcc的版本是MSYS2 mingw64的10.2.0:
assembly - 为什么 MIPS 堆栈基数是 0x7ffffffc 而不是 0x80000000
为什么 MIPS 堆栈基数是 0x7ffffffc 而不是 0x80000000?
如果我理解正确,堆栈指针是指放置在堆栈上的最后一项。那么,如果是这种情况,这是否意味着地址 0x7ffffffc 永远不会被使用,因为将整数压入堆栈的传统方法是将 $sp 递减到 0x7ffffff8 并将压入的值放在那里?
assembly - 组装中的“对齐堆栈”是什么意思?
堆栈对齐在 ASMx64 中如何工作?什么时候需要在函数调用之前对齐堆栈,需要减去多少?
我不明白它的目的是什么。我知道还有其他关于此的帖子,但对我来说还不够清楚。例如:
assembly - 在 MIPS 中推送堆栈指针
我知道推送堆栈指针,但我不确定如何推送所有元素。
这就是我定义堆栈指针的方式。
如何推动和移除它们?我只是
还是循环6次?感谢您提前提供帮助。