我正在查看TriCore TC1797代码,以及匹配指令集手册TriCore V1.3.1指令集。
我的问题很简单,但Tasking编译器生成的汇编代码令我感到困惑。代码看起来将永远循环,但它没有,代码工作。怎么可能?
让我们采取这些指令行(评论是我对操作的理解):
MOVH.A a12, #@HIS(VAR_ADDRESS)
LEA a12, [a12]@LOS(VAR_ADDRESS)
LD.H d15, [a12]0 ; d15 = 4 (half-word) passed to this function
; values passed are either 0x04 or 0x10 or 0xA8
loop_addr:
ADD d15, d15, #-0x10 ; d15 = 4 - 0x10 = 0xFFFFFFF4
EXTR d9, d15, #0, #16 ; d9 = 0x0000FFF4
; edit: THIS IS MY MISTAKE
; correct is d9 = 0xFFFFFFF4
...
other code here, never touching d9
...
ST.H [a12], d9 ; store decremented value back
JGE d9, #1, loop_addr ; ???? comparing 0x0000FFF4 to 1
; will it loop forever?
我不明白,因为d9总是一个正数(对吗?),它永远不会是零,循环退出怎么可能?
感谢您澄清,我在手册中重新阅读了该内容,但无法找到解释此情况。
答案 0 :(得分:2)
ADD d15, d15, #-0x10 ; d15 = 4 - 0x10 = 0xFFFFFFF4
EXTR d9, d15, #0, #16 ; d9 = 0x0000FFF4
这是错误的。 EXTR
符号扩展了提取的位域。引用manual:
EXTR指令填充结果的最高有效位 对提取的位字段进行符号扩展(复制 比特字段的最高位。)
因此d9
实际上是0xFFFFFFF4
。 JGE
使用已签名的比较,因此可以正确地视为-12
并终止循环。