【发布时间】:2023-03-18 13:26:02
【问题描述】:
我正在学习汇编语言(针对 68000 微处理器),我遇到了以下问题:
编写一个 68000 的汇编语言程序,将执行 5*X + 6*Y+ [Y/8] -> [D1.L],其中 x 是存储在最低字节中的无符号 8 位数 D0 和 Y 是一个 16 位有符号数,存储在 D1 的高 16 位中。忽略其余部分 年/8 岁。
这就是解决方案:
ANDI.W #$OOFF,DO ;CONVERT X TO UNSIGNED 16-BIT
MULU.W #5,DO ;COMPUTE UNSIGNED 5*X IN D0.L
SWAP.W D1 ;MOVE Y TO LOW 16 BITS IN D1
M0VE.W D1 ,D2 ;SAVE Y TO LOW 16 BITS OF D2
MULS.W #6,D1 ;COMPUTE SIGNED 6*Y IN D1.L
ADD.L DO,D1 ;ADD 5*X WITH 6*Y
EXT.L D2 ;SIGN EXTEND Y TO 32 BITS
ASR.L #3,D2 ;PERFORM Y/8;DISCARD REMAINDER
ADD.L D2,Dl ;PERFORM 5*X+6*Y +Y/8
FINISH JMP FINISH
但是,我不明白第一行。我想我们必须将它转换为 16 位,因为 Y 是一个 16 位有符号数,但我不明白 ANDI 指令在这种情况下是如何工作的。
此外,在示例中,他们使用ASR.L #3,D2将 D2 除以 8;所以如果我使用ASR.L #2,D2那么我会将D2除以4?或者它是如何工作的?
如果我使用LSL.L #3,D2,那么我会将 D2 乘以 8?
最后,为什么他们将 Y 符号扩展为 32 位?
感谢您的帮助!
【问题讨论】:
-
其中有 OCR 错误吗?
M0VE而不是MOVE(零与大写-O)?而add.l D2, Dl而不是 D1。 (lcase ell 与一个)。不过,感谢您没有发布文字图片。 -
问题引用的问题不清楚何时应该将事物扩展到 32 位。这就像
((int32_t)y)>>3 + ((int16_t)(5*(uint16_t)x + 6*y)),所以 5x+6y 结果在与 y/8 相加之前被截断为 16 位。 -
另请注意,算术右移与有符号整数除法的语义不同(例如,在零附近的区域中)。见compiler output for both ways。所以这个答案是基于
/的非 C 语义。不过,我不明白为什么它和结果在[]中。