手动编译程序集

时间:2012-10-11 20:32:56

标签: compilation assembly

我在将汇编中的特定行转换为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(标签)" 。变量" r8"," r0"和"标签"如上所述,不要改变。

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

00000000000000001100001101010000

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

0000000000000000

...添加第15位(这很令人困惑,因为他们不会告诉我它是否值得2 ^ 15或2 ^ 0,我已尝试过两者并且根本不添加在所有)

0000000000000001
1000000000000000
0000000000000000

一切都不正确。

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

1 个答案:

答案 0 :(得分:0)

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

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

orhi  r8, r0, %hiadj(label) --> 00000 01000 0000000000000000 110010
addi  r8, r8, %lo(label) --> 01000 01000 1100001101010000 000100