0

我无法将汇编中的特定行翻译为Nios II的机器代码。我已经成功编译了这些行:

START_TIMER = 0xF68C
r0 = 0x0
r8 = 0x8
label = 50000

#orhi r8, r0, %hiadj(label) --> 00000 01000 ???????????????? 110010
addi r8, r8, %lo(label) --> 01000 01000 1100001101010000 000100
subi r8, r8, 1 --> 01000 01000 1111111111111111 000100
bne r8, r0, START_TIMER --> 01000 00000 1111011010001100 011110

我遇到问题的行是 IMM16 在这一行:

orhi r8, r0, %hiadj(label)

如上面链接的手册中所述,“%lo”表示“提取 immed32 的位 [15..0]”,“%hiadj”表示“提取位 [31..16] 并添加 immed32 的第 15 位”。但是,二进制的 50000 是 1100001101010000,因此是 16 位数字。据我所知,它不包含 16 到 31 之间的任何位。我尝试使用 0000000000000001,但它不正确。

我究竟做错了什么?

编辑: 只是为了消除任何误解;我只是想知道如何手动编译 "orhi r8, r0, %hiadj(label)"。变量“r8”、“r0”和“label”如上所述,不变。

编辑 2: 我尝试将 50000 转换为 32 位二进制文​​件:

00000000000000001100001101010000

...提取位 [31...16]:

0000000000000000

...添加第 15 位(这很令人困惑,因为他们没有告诉我它是值 2^15 还是 2^0,我已经尝试了两者,根本不添加)

0000000000000001
1000000000000000
0000000000000000

都是不正确的。

编辑 3: 根据此链接,当 16 位值为 0x8000 或更大时,它将其余部分符号扩展为 0xffff8000 并将位 [31...16] 加 1,这会将数字重载为 0x100008000 ~ 0x00008000,即你说的,杰拉德,但显然仍然不正确。

4

1 回答 1

0

您提供的代码采用“标签”处的值,这是一个 16 位半字,并将其扩展为 32 位字以成为地址。由于您的标签是 16 位值,因此您必须将零移到寄存器的上半部分。

所以你想要做的是将零加载到高位,然后添加低位......

orhi  r8, r0, %hiadj(label) --> 00000 01000 0000000000000000 110010
addi  r8, r8, %lo(label) --> 01000 01000 1100001101010000 000100
于 2012-10-11T21:59:19.750 回答