- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我看一些内存分段文档是这样理解的:函数调用时,有几条指令(称为函数序言)将帧指针保存在栈中,将栈指针的值复制到基指针中并为局部变量节省一些内存。
这是我尝试使用 GDB 调试的一个简单代码:
void test_function(int a, int b, int c, int d) {
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() {
test_function(1, 2, 3, 4);
}
调试此代码的目的是了解调用函数时堆栈中发生的情况:因此我必须在程序执行的各个步骤(调用函数之前和执行期间)检查内存。虽然我通过检查基指针设法看到了返回地址和保存的帧指针之类的东西,但我真的无法理解反汇编代码后我要写什么。
拆解:
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400509 <+0>: push rbp
0x000000000040050a <+1>: mov rbp,rsp
0x000000000040050d <+4>: mov ecx,0x4
0x0000000000400512 <+9>: mov edx,0x3
0x0000000000400517 <+14>: mov esi,0x2
0x000000000040051c <+19>: mov edi,0x1
0x0000000000400521 <+24>: call 0x4004ec <test_function>
0x0000000000400526 <+29>: pop rbp
0x0000000000400527 <+30>: ret
End of assembler dump.
(gdb) disassemble test_function
Dump of assembler code for function test_function:
0x00000000004004ec <+0>: push rbp
0x00000000004004ed <+1>: mov rbp,rsp
0x00000000004004f0 <+4>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004f3 <+7>: mov DWORD PTR [rbp-0x18],esi
0x00000000004004f6 <+10>: mov DWORD PTR [rbp-0x1c],edx
0x00000000004004f9 <+13>: mov DWORD PTR [rbp-0x20],ecx
0x00000000004004fc <+16>: mov DWORD PTR [rbp-0x4],0x7a69
0x0000000000400503 <+23>: mov BYTE PTR [rbp-0x10],0x41
0x0000000000400507 <+27>: pop rbp
0x0000000000400508 <+28>: ret
End of assembler dump.
我知道“将帧指针保存在堆栈上”是通过“push rbp”完成的,“将堆栈指针的值复制到基指针中”是通过“mov rbp, rsp”完成的,但是是什么让我令人困惑的是缺少用于“为局部变量节省一些内存”的“sub rsp $n_bytes”。我在很多展览中都看到了这一点(甚至在 stackoverflow 上的某些主题中)。
我还读到参数应该与基指针有一个正偏移量(在它被堆栈指针值填充之后),因为如果它们位于调用函数中并且堆栈向较低地址增长,那么当基指针更新为堆栈指针值,编译器通过添加一些正数返回堆栈。但是我的代码似乎将它们存储在负偏移量中,就像局部变量一样。我也无法理解为什么将它们放在那些寄存器中(主要)。它们不应该直接保存在 rsp 中“offsetted” “?
也许这些差异是由于我使用的是 64 位系统,但我的研究并没有让我找到任何可以解释我所面临的问题的东西。
最佳答案
x86-64 的 System V ABI 在 %rsp
下指定了一个 128 字节的 red zone
。这 128 个字节属于函数,只要它不调用任何其他函数(它是一个叶函数)。
信号处理程序(和调试器调用的函数)需要遵守红色区域,因为它们实际上是非自愿函数调用。
test_function
的所有局部变量,即叶函数,适合红色区域,因此不需要调整 %rsp
。 (此外,该函数没有明显的副作用,可以根据任何合理的优化设置进行优化)。
您可以使用 -mno-red-zone
进行编译,以阻止编译器使用堆栈指针下方的空间。内核代码必须这样做,因为硬件中断不会实现红区。
关于c - 为什么这个函数序言中没有 "sub rsp"指令,为什么函数参数存储在负 rbp 偏移处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45860023/
我有一个非常基本的 MySQL 查询,它从数据库表中读取行并将行值添加或减去定义为 $total_balance 的 PHP 字符串。 例如; $statement_details_query = m
我有 following fiddle ,请注意,如果您使输出的宽度变小,图像将被覆盖并且不会出现滚动条 - 完美。 如果我attempt the same effect on the right ,
这个正则表达式将得到 456。我的问题是为什么它不能是 1-234-56 中的 234 ? 56 是否限定 (?!\d)) 模式,因为它不是单个数字。 (?!\d)) 寻找的起始点在哪里? impor
我需要知道两个子结构之间的内存距离 (&my_type.a - &my_tape.b.c) 结果的类型是什么?我需要将它转换为 (signed int),所以显然它是别的东西。 最佳答案 根据 C11
我遇到了一个扩展异常的异常处理程序类,如下所示: public class AppFileReaderException extends Exception { //Explicit seri
如何可视化负 RGB 值? 根据 OpenCV 文档: CV_8S - 8 位有符号整数 (-128..127) 这是否意味着 -128 表示 0 而 127 表示 255? 如果是,那我们为什么需要
我这里有一段代码给我带来了麻烦: idIndex = panoBuffer.indexOf("\"photo_id\":"); System.out.println(idIndex);
我刚刚练习 Java,对此还很陌生。我只是想创建一个随机数生成器程序来跟踪玩家的获胜、失败、获胜百分比和总获胜金额。该程序的逻辑是,玩家每次 session 有 3 次机会,计算机会生成一个随机数,玩
因此,我们被要求创建一个程序,使用户能够从 1-6 个有关矩阵运算的选项中进行选择。在每个用户的输入中,我们需要检查该输入是否适合要完成的操作(程序应该接受整数或 float ,正数或负数)。如果不满
这是我期望的输出 x |x| 1.2 1.2 -2.3 2.3 3.4 3.4 但我一直收到这个: x |x| 1
假设我有这个: $date1=date_create(date('H:I', strtotime('8:00'))); $date2=date_create(date('H:I', strtotime
如何确定负 FixNum 的无符号解释? # unexpected, true (~0b01111011).to_s(2) == ("-" + (~0b01111011).abs.to_s(2)) #
这是一个用于“邀请您的 friend 加入此群组”脚本的快速 SQL 查询。 我有 2 个表:users 和 group_members。我正在尝试执行一个查询,选择我所有的 friend ——由第一
负 ASCII 值有什么意义? int a = '«'; //a = -85 but as in ASCII table '<<' should be 174 最佳答案 没有负数ASCII值。 ASC
我知道用 PHP 可以做到这一点,但是有没有办法只用 MySQL 来做到这一点? 我有这个数据库: --------------------------------------------------
我在变量中有一个时间戳 $data = (float) -2208988800; 是否可以根据这些数据创建正确的日期?date("d.M.Y", $data) 返回“07.02.2036” 最佳答案
你好我如何将括号格式的负值转换为 double 值。目前我有这个。 Payment.Text = Calc_Payment().ToString("#,##0.00;(#,##0.00)"); 将支付
这是一个小程序。这应该打印 0 或 1,还是它有未定义的行为? #include struct S0 { unsigned f1 : 1; }; struct S0 s; int main (v
运行 lgb.cv 时,我有时会从日志中看到“从分数开始训练”后的负数。想知道这个数字到底是什么意思,单位是什么?是根据参数中指定的指标吗?以下是摘录: [LightGBM] [Info] Total
我正在使用变分自动编码器类型模型,我的损失函数的一部分是均值为 0 和方差为 1 的正态分布与另一个均值和方差由我的模型预测的正态分布之间的 KL 散度。 我用以下方式定义了损失: def kl_lo
我是一名优秀的程序员,十分优秀!