2012-09-01 15 views
4
中间

我期待在C应用有什么可以“日航”的原因到另一个功能的MIPS

80019B90     jal  loc_80032EB4 

loc_80032EB4是在另一个函数体中间的一个非常可疑拆卸MIPS代码,我特别检查了在运行时在这个地址没有加载其他代码,并且以这种方式调用该函数(在开始时传递一些代码)会很有用。但是在C中怎么做呢?这不是goto,因为你不能转到另一个函数,并且正常的函数调用将始终“开始”。这可以是一些手工优化吗?

更新:

简体两种功能,被叫的布局:

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使用情况,但在我的测试中,我总是可以看到调用t o setjmp和longjmp在反汇编代码中运行,而不是直接跳转。

更新3: 我一直在使用以获得标签指针GCC特定能力尝试和铸造此函数指针,结果是接近我想要什么,但反汇编代码仍然是不同的,而不是使用JAL与exaxct的解决它计算它的运行时间,也许我只是无法强制编译器将此值视为常量,因为范围问题。

+0

没有足够的上下文来回答这个问题。这是'jal'在有效的代码?它跳到了什么地方? – ninjalj

+0

我已经更新了功能布局的问题。该jal是有效的代码,并以这种方式使用它是有道理的。 – Riz

+1

这确实是stange。那是哪个编译器?我认为即使编译器在两个不同的调用站点中嵌入了裸函数,也不能在gcc中执行此操作。 – ninjalj

回答

1

由于它是游戏系统的数据解压缩功能,因此该功能很可能是具有多个入口点的手动优化装配。多个入口点不常用,所以很难找到一个公开可用的示例,但here是gcc邮件列表中的一个旧线程,它暗示了该技术的一种可能用法。

要点是,如果你有两个功能,其中一个功能F1有代码,其它功能的一个子集,F2的代码,然后F2代码就告吹成代码对于F1。在你的情况下,F2为解压缩的数据分配内存,并且F1假定内存分配已经完成。我很确定GCC 2.9x不能生成这样的代码。

不可能将此构造从汇编器直接转换为标准C,因为C中不能使用goto中的另一个函数,但这在汇编代码中是完全合法的。 gcc邮件列表线程提出了几种解决方法来表达C中的相同想法。

如果您查看解压缩的拆装代码,它可能会具有与编译器生成的代码不同的样式。甚至可能会使用一些操作码,如编译器无法从C生成的find first set bit

+0

不幸的是,我不能发现任何解压缩代码和调用者函数风格上的差异。要尝试多个入口点,你可以请我链接到一个例子,我找不到一个... – Riz

+0

尽管尝试真的很难找到任何编译标志和各种代码片段的神奇组合,我找不到任何方式强制编译器没有asm就像这样行为,所以你的想法似乎是正确的。尽管如此我会更新这个问题,如果我找到一个能够做到这一点的C代码。 – Riz

相关问题