【问题标题】:Can help me with mips translating to binary?可以帮助我将 mips 转换为二进制文件吗?
【发布时间】:2016-06-04 23:29:56
【问题描述】:

我不明白如何翻译标签。任何人都可以帮助我

假设我们有以下代码:

loop: 
    add $t2,$t2,$t1 
    addi $t2,$t2,4 
    sw $t2,4($s0) 
    bne $t2,20,loop 
    jr $ra

如何转换成二进制bne $t2,10,loop

【问题讨论】:

  • 这是一个名为 assembler 的程序的工作,它接受 assembly code 并将其转换为机器 bytecode。您通常不会手动执行此操作。
  • 如果您手动操作,则需要计算“bne”和“loop:”之间的字节数,并将该计数替换为“loop”参数。
  • 所以如果它运行的是 32 位指令,bne $t2,10,loop 中的 in "loop" 的值应该是 -12。如 4 字节 på 行和 3 行。现在查找 MIPS 指令的信息here.. 我的猜测是二进制文件将类似于:0001 01ss sss0 1010 1111 1111 1111 0110.. 不过我不确定..
  • @Rapsefar 不,该值应该是-16,因为要跳转的行数是从跳转指令后的一行开始计算的。另请注意,操作码中实际存储的内容将是-4,因为操作码中的值将乘以 4 来计算跳跃距离。

标签: mips


【解决方案1】:

有几点需要注意。

分支偏移总是从分支地址+4(即PC+4)计算出来的,所以它是相对于jr指令的地址的。

由于 mips 指令必须与字[四字节边界]对齐,因此指令地址的最右边两位将[必须始终为]零。

mips 架构通过将分支偏移编码为 word 偏移来利用这一点(即字节偏移右移 2)。这将分支指令 16 位立即编码的范围扩展到 18 位。

所以,这里是列表:

00:     loop:
00:         add     $t2,$t2,$t1
04:         addi    $t2,$t2,4
08:         sw      $t2,4($s0)
0C:         bne     $t2,20,loop
10:         jr      $ra

jr 地址为0x10,因此循环的字节偏移量为-0x10,编码偏移量为-0x04 或0xFFFC,bnexxxxFFFC

但是……这有问题。这个特殊的bne 使用 immediate 值作为第二个参数。这使得bne 成为伪操作,不是简单的bne 指令。

所以,实际的顺序变成:

00:     loop:
00:         add     $t2,$t2,$t1
04:         addi    $t2,$t2,4
08:         sw      $t2,4($s0)
0C:         addi    $at,$zero,20
10:         bne     $at,$t2,loop
14:         jr      $ra

注意bne变成了两个指令序列:addibne

jr 地址现在是 0x14,因此循环的字节偏移量为 -0x14,编码偏移量为 -0x05 或 0xFFFB,bnexxxxFFFB

bne 汇编器格式为:

    bne    s,t,label

bne 编码为:

0001 01ss ssst tttt iiii iiii iiii iiii

所以,s 寄存器是 $at$1 --> 00001

t 寄存器是$t2$10 --> 01010

所以,现在我们有:

0001 01ss ssst tttt iiii iiii iiii iiii
       00 0010 1010
0001 0100 0010 1010 iiii iiii iiii iiii

在十六进制中,这是142Ayyyy。我们已经知道yyyyFFFB,所以最终的十六进制值为:142AFFFB

【讨论】:

    【解决方案2】:

    Branch on not equal 的语法为 bne rs,rt,label,其中前 6 位是操作码,接下来的 5 位是 rs,接下来的 5 位是 rt,其余的是分支目标地址的标签:

    BTA = PC + 4 + imm * 4

    这是通过符号扩展立即数,乘以 4 并将其和 4 添加到程序计数器来计算的。有关解释,请参阅此问题

    How to Calculate Jump Target Address and Branch Target Address?

    bne 格式是立即数(I 型)。操作码是 5 (000101)。例如,此机器代码打印字母表中的每三个字符。

    00100100000100000000000000110000
    00000000000100000010000000100001
    00100100000000100000000000001011
    00000000000000000000000000001100
    00100010000100000000000000000011
    00100100000010000000000001011101
    00010110000010001111111111111010
    00000000000000000000000000000000
    00001000000100000000000000001000
    00000000000000000000000000000000
    

    它是 10 行(10 条指令)。第 7 行是一个分支,它的机器代码为 00010110000010001111111111111010。前 6 个数字000101 是操作码 5。然后是 5 + 5 位寄存器(在本例中寄存器是 $16 和 $8,其余的是立即分支目标地址。

    同样,你的程序

    .text
    loop: 
        add $t2,$t2,$t1 
        addi $t2,$t2,4 
        sw $t2,4($s0) 
        bne $t2,20,loop 
        jr $ra
    

    将机器码翻译成7行:

    00000001010010010101000000100000
    00100001010010100000000000000100
    10101110000010100000000000000100
    00100000000000010000000000010100
    00010100001010101111111111111011
    00000011111000000000000000001000
    

    实际的翻译是这样的

     Address    Code        Basic                     Source
    
    0x00400000  0x01495020  add $10,$10,$9        3        add $t2,$t2,$t1 
    0x00400004  0x214a0004  addi $10,$10,0x00000004        addi $t2,$t2,4 
    0x00400008  0xae0a0004  sw $10,0x00000004($16)5        sw $t2,4($s0) 
    0x0040000c  0x20010014  addi $1,$0,0x00000014 6        bne $t2,20,loop 
    0x00400010  0x142afffb  bne $1,$10,0xfffffffb      
    0x00400014  0x03e00008  jr $31                7        jr $ra
    

    ...倒数第二行是 bne : 00010100001010101111111111111011 。前 6 位 000101 是操作码,接下来的 5 (00001) + 5 (01010) 位是寄存器,其余 (1111111111111011) 是分支目标地址的立即值(十六进制1111111111111011=FFFB

    有关详细信息,请参阅MIPS manual

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 2020-12-24
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 2020-10-06
      相关资源
      最近更新 更多