【发布时间】:2010-07-19 22:21:45
【问题描述】:
编译器(例如 gcc)生成将一些空内存元素加载到寄存器中的指令是否常见?就像... lw at,0(sp) where memory[sp + 0] = 0. 这基本上只是将 0 放入 $at ($R1.) 我问是因为我正在查看可执行文件的十六进制转储(可执行文件是编译 c++ 文件的结果),我正在手动验证它,如果我从 objdump 状态入口点开始,我会遇到执行此操作的指令。如果这只是一个常见的编译器操作,我不确定是否应该将其视为错误。将寄存器归零似乎是一种糟糕的方法。添加 $at,$0,$0 会更好。或 SLL $at,$0,$0..
入口点是 400890。最后 jal 的跳转目标是一个空的内存位置(告诉我可能有问题...)请注意,我之前的示例是故意仲裁的。
为了清楚起见,-32636+gp 是一个空的内存位置。如果您需要证据,我可以在此时发布内存内容:)。
00400890 <__start>:
400890: 03e00021 move zero,ra
400894: 04110001 bal 40089c <__start+0xc>
400898: 00000000 nop
40089c: 3c1c0fc0 lui gp,0xfc0
4008a0: 279c7864 addiu gp,gp,30820
4008a4: 039fe021 addu gp,gp,ra
4008a8: 0000f821 move ra,zero
4008ac: 8f848034 lw a0,-32716(gp)
4008b0: 8fa50000 lw a1,0(sp)
4008b4: 27a60004 addiu a2,sp,4
4008b8: 2401fff8 li at,-8
4008bc: 03a1e824 and sp,sp,at
4008c0: 27bdffe0 addiu sp,sp,-32
4008c4: 8f878054 lw a3,-32684(gp)
4008c8: 8f888084 lw t0,-32636(gp)<------ this instruction
4008cc: 00000000 nop
4008d0: afa80010 sw t0,16(sp)
4008d4: afa20014 sw v0,20(sp)
4008d8: afbd0018 sw sp,24(sp)
4008dc: 8f998068 lw t9,-32664(gp)
4008e0: 00000000 nop
4008e4: 0320f809 jalr t9
4008e8: 00000000 nop
Jal 目标是 4010c0。
4010c0: 8f998010 lw t9,-32752(gp)
4010c4: 03e07821 move t7,ra
4010c8: 0320f809 jalr t9
【问题讨论】:
-
我不熟悉 MIPS,但肯定是从堆栈中加载一个值 - 可能是一个函数参数,可能由运行时提供以提供命令行参数,如果这是程序条目观点。该值要到运行时才能知道,因此编译器不能假定它为零。
-
我实际上是在运行时谈论这条指令。含义这将是程序入口点之后的指令 10 或其他内容,并且在此之前没有分配要从中加载的内存元素的指令。这告诉我,要么是故意的(应用不佳)nop,要么是可执行文件的一部分应该在 .text 部分之前加载。
-
您可以添加更多上下文吗?也许在前后贴上 5-10 条指令?
-
不是跳转到t9,不是t0吗? t9 是 -32664(gp),而不是 -32636+gp
-
“我正在手动验证它”。伙计,我不知道你的工作是什么,但它非常核心。
标签: c++ compiler-construction assembly mips