You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

反编译PS2游戏MIPS汇编:先加载立即数再移位的代码功能咨询

解析PS2 MIPS汇编中的有符号数向零取整除法模式

你遇到的这段重复出现的汇编代码,是实现有符号数除以2的幂时的向零取整操作,对应C语言标准的整数除法行为,并非abs取绝对值函数。

第一个示例(除以2)

这段汇编:

li     v1,2
sra    v1,s1,1
bgez   s1,*+16
nop    
addiu  v1,s1,1
sra    v1,v1,1
daddu  s1,v1,$0

对应的C代码逻辑为:

s1 = (s1 >= 0) ? (s1 >> 1) : ((s1 + 1) >> 1);

完全等价于C语言中的:

s1 = s1 / 2;

这么实现的原因是:MIPS的sra(算术右移)指令对负数执行的是向负无穷取整,但C语言规定有符号整数除法必须是向零取整。比如:

  • 当s1 = -3时,直接sra s1, 1会得到-2(向负无穷取整),但C语言中-3 / 2的结果是-1(向零取整),所以需要先给负数加1再右移,修正结果。
  • 正数的算术右移结果和向零取整的除法结果一致,无需调整。

第二个示例(除以256)

移位8位的版本:

li     v1,256
sra    v1,s1,8
bgez   s1,*+16
nop    
addiu  v1,s1,255
sra    v1,v1,8
daddu  s1,v1,$0

对应的C代码是:

s1 = (s1 >= 0) ? (s1 >> 8) : ((s1 + 255) >> 8);

等价于:

s1 = s1 / 256;

这里的255是2^8 - 1,和第一个例子逻辑完全一致:针对负数,先加上2^n - 1(n为移位位数)再右移,把MIPS算术右移的取整规则修正为C语言要求的向零取整。

为什么不是abs函数?

abs函数的作用是取绝对值,而这段代码本质是除法取整。你最初在数组索引前遇到它,只是因为除法结果恰好被用作非负索引,但它的适用场景是所有需要对有符号整数执行除以2的幂的运算的地方——哪怕结果允许为负,只要是符合C语言整数除法规则的场景,就会生成这段汇编。

内容的提问来源于stack exchange,提问作者user16316067

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:23:32