我正在查看一个非常可疑的 C 应用程序的反汇编 MIPS 代码
80019B90 jal loc_80032EB4
loc_80032EB4 位于另一个函数主体的中间,我特别检查了运行时没有在此地址加载其他代码,并且以这种方式调用该函数(在开头传递一些代码)可能很有用。但是在 C 中怎么可能呢?这不是 goto,因为您无法转到另一个函数,并且正常的函数调用将始终“jal”到开头。这可以是一些手动优化吗?
更新:
两个函数的简化布局,被调用者:
sub_80032E88 (lz77_decode)
... save registers ...
80032E90 addiu $sp, -8
... allocate memory for decompressed data ...
80032EB0 move DECOMPRESSED_DATA_POINTER_A1, $v0
loc_80032EB4:
80032EB4 lw $t7, 0(PACKED_DATA_POINTER_A0)
... actual data decompression ...
80032F4C jr $ra
呼叫者:
80019ACC addiu $sp, -0x30
... some not related code ...
80019B88 lw $a1, off_80018084 // A predefined buffer is used instead of allocating it for decompressed data
80019B90 jal loc_80032EB4
80019B94 move $a0, $s0
... some other code and function epilogue ...
更新 2: 我检查了这是否可能是使用 setjmp/longjmp 的情况,但在我的测试中,我总是可以在反汇编代码中看到对 setjmp 和 longjmp 函数的调用,而不是直接跳转。
更新 3: 我尝试使用 GCC 特定的功能来获取标签指针并将这个指针转换为函数,结果接近我想要的但反汇编代码仍然不同,而不是使用带有 exaxct 地址的 jal 它计算它的运行时,也许由于范围问题,我无法强制编译器将此值视为常量。