← 返回笔记列表

2.4的误区~

2026-03-15
计组汇编

1. 关于"ADD 不更新状态位,进位丢失"
- **32位结果本身没错**:`ADD r0, r1, r2` 永远给出正确的低 32 位结果.如果你只做 32 位整数运算,这个结果就是你要的,进位丢失没关系.
- **但如果你需要高32位(比如64位运算)**:那就必须用 `ADDS`(更新进位)和 `ADC`(带进位加)(计算结果加进位位),否则高32位就丢了——这确实是你**选错了指令**,就像需要64位积却用了 `MUL` 而不是 `UMULL` 一样.(后面会说乘法的结果有可能需要两个32位保存)

2. 关于"状态位不更新对 CMP/BEQ 的影响"
- **CMP 本身会更新状态位**:`CMP r0, r1` 实际上做的是 `r0 - r1`,并且**总是更新状态位**(相当于 `SUBS` 但不存结果).所以 `CMP` 不受前面指令是否更新的影响,它自己会设置正确的标志.
- **问题出在 BEQ 等条件跳转**:`BEQ` 检查的是 **Z 标志**.如果它前面的指令(比如 `ADD`)没有更新 Z 标志,那么 `BEQ` 看到的是更早之前某条指令留下的 Z 值,这显然会导致错误的跳转.所以**如果要用条件分支判断某条指令的结果,就必须确保那条指令更新了状态位**(比如用 `ADDS` 而不是 `ADD`).
也就是说我们上一节说的那个加法错误,本质上是我们选错了模式,导致了相加错误,就和c语言一样我们不应该用int,该用long int,所以说计算机这个我们计算的低32位的结果永远是对的,我们产生错误,是人为的选错了模式,这时候要用64位
总结观点
- 不更新状态位导致的问题,本质是**程序员的选择错误**(该用 `ADDS`/`ADC` 时用了 `ADD`).
- 32位加减本身的结果总是对的,丢失的进位是高精度运算需要的额外信息.
- 条件判断依赖于最新的状态位,如果前一条指令没更新,就会读到过时的标志.