将 MIPS 程序集转换为 C

Converting MIPS assembly to C

我正在将 MIPS 转换为 C,我已经坚持了好几天。

我已经开始手动将 MIPS 转换为 C,尽管我已经为此工作了几天,但我在 C 中生成的程序仍然没有 运行 需要,我觉得就像我忽略了一个小错误,非常感谢你的帮助。

我从 toplevel_fnc 开始转换,然后是 subroutine_fnc。

这是 MIPS 代码的一部分。

子程序:

build/program-mips:     file format elf32-tradbigmips


Disassembly of section my_text:

00404ed0 <subroutine_fnc>:
  404ed0:   27bdffd8    addiu   sp,sp,-40
  404ed4:   afbe0024    sw  s8,36(sp)
  404ed8:   03a0f025    move    s8,sp
  404edc:   afc40028    sw  a0,40(s8)
  404ee0:   8fc40028    lw  a0,40(s8)
  404ee4:   27c20018    addiu   v0,s8,24
  404ee8:   00402825    move    a1,v0
  404eec:   24060001    li  a2,1
  404ef0:   24020fa3    li  v0,4003
  404ef4:   0000000c    syscall
  404ef8:   afc70008    sw  a3,8(s8)
  404efc:   afc2000c    sw  v0,12(s8)
  404f00:   8fc20008    lw  v0,8(s8)
  404f04:   00000000    nop
  404f08:   14400004    bnez    v0,404f1c <subroutine_fnc+0x4c>
  404f0c:   00000000    nop
  404f10:   8fc2000c    lw  v0,12(s8)
  404f14:   10000002    b   404f20 <subroutine_fnc+0x50>
  404f18:   00000000    nop
  404f1c:   2402ffff    li  v0,-1
  404f20:   afc20010    sw  v0,16(s8)
  404f24:   8fc20010    lw  v0,16(s8)
  404f28:   00000000    nop
  404f2c:   04410006    bgez    v0,404f48 <subroutine_fnc+0x78>
  404f30:   00000000    nop
  404f34:   24040001    li  a0,1
  404f38:   24020fa1    li  v0,4001
  404f3c:   0000000c    syscall
  404f40:   afc70008    sw  a3,8(s8)
  404f44:   afc20014    sw  v0,20(s8)
  404f48:   8fc20010    lw  v0,16(s8)
  404f4c:   00000000    nop
  404f50:   14400004    bnez    v0,404f64 <subroutine_fnc+0x94>
  404f54:   00000000    nop
  404f58:   00001025    move    v0,zero
  404f5c:   10000002    b   404f68 <subroutine_fnc+0x98>
  404f60:   00000000    nop
  404f64:   83c20018    lb  v0,24(s8)
  404f68:   03c0e825    move    sp,s8
  404f6c:   8fbe0024    lw  s8,36(sp)
  404f70:   27bd0028    addiu   sp,sp,40
  404f74:   03e00008    jr  ra
  404f78:   00000000    nop

和顶层:

00404f7c <toplevel_fnc>:
  404f7c:   27bdffc0    addiu   sp,sp,-64
  404f80:   afbf003c    sw  ra,60(sp)
  404f84:   afbe0038    sw  s8,56(sp)
  404f88:   03a0f025    move    s8,sp
  404f8c:   afc00018    sw  zero,24(s8)
  404f90:   10000040    b   405094 <toplevel_fnc+0x118>
  404f94:   00000000    nop
  404f98:   83c30034    lb  v1,52(s8)
  404f9c:   2402005c    li  v0,92
  404fa0:   14620022    bne v1,v0,40502c <toplevel_fnc+0xb0>
  404fa4:   00000000    nop
  404fa8:   8fc20018    lw  v0,24(s8)
  404fac:   00000000    nop
  404fb0:   24420001    addiu   v0,v0,1
  404fb4:   afc20018    sw  v0,24(s8)
  404fb8:   24040001    li  a0,1
  404fbc:   3c020041    lui v0,0x41
  404fc0:   244260e0    addiu   v0,v0,24800
  404fc4:   00402825    move    a1,v0
  404fc8:   24060002    li  a2,2
  404fcc:   24020fa4    li  v0,4004
  404fd0:   0000000c    syscall
  404fd4:   afc7001c    sw  a3,28(s8)
  404fd8:   afc20020    sw  v0,32(s8)
  404fdc:   8fc2001c    lw  v0,28(s8)
  404fe0:   00000000    nop
  404fe4:   14400004    bnez    v0,404ff8 <toplevel_fnc+0x7c>
  404fe8:   00000000    nop
  404fec:   8fc20020    lw  v0,32(s8)
  404ff0:   10000002    b   404ffc <toplevel_fnc+0x80>
  404ff4:   00000000    nop
  404ff8:   2402ffff    li  v0,-1
  404ffc:   afc20024    sw  v0,36(s8)
  405000:   8fc20024    lw  v0,36(s8)
  405004:   00000000    nop
  405008:   04410022    bgez    v0,405094 <toplevel_fnc+0x118>
  40500c:   00000000    nop
  405010:   24040001    li  a0,1
  405014:   24020fa1    li  v0,4001
  405018:   0000000c    syscall
  40501c:   afc7001c    sw  a3,28(s8)
  405020:   afc20028    sw  v0,40(s8)
  405024:   1000001b    b   405094 <toplevel_fnc+0x118>
  405028:   00000000    nop
  40502c:   24040001    li  a0,1
  405030:   27c20034    addiu   v0,s8,52
  405034:   00402825    move    a1,v0
  405038:   24060001    li  a2,1
  40503c:   24020fa4    li  v0,4004
  405040:   0000000c    syscall
  405044:   afc7001c    sw  a3,28(s8)
  405048:   afc2002c    sw  v0,44(s8)
  40504c:   8fc2001c    lw  v0,28(s8)
  405050:   00000000    nop
  405054:   14400004    bnez    v0,405068 <toplevel_fnc+0xec>
  405058:   00000000    nop
  40505c:   8fc2002c    lw  v0,44(s8)
  405060:   10000002    b   40506c <toplevel_fnc+0xf0>
  405064:   00000000    nop
  405068:   2402ffff    li  v0,-1
  40506c:   afc20024    sw  v0,36(s8)
  405070:   8fc20024    lw  v0,36(s8)
  405074:   00000000    nop
  405078:   04410006    bgez    v0,405094 <toplevel_fnc+0x118>
  40507c:   00000000    nop
  405080:   24040001    li  a0,1
  405084:   24020fa1    li  v0,4001
  405088:   0000000c    syscall
  40508c:   afc7001c    sw  a3,28(s8)
  405090:   afc20030    sw  v0,48(s8)
  405094:   00002025    move    a0,zero
  405098:   0c1013b4    jal 404ed0 <subroutine_fnc>
  40509c:   00000000    nop
  4050a0:   00021600    sll v0,v0,0x18
  4050a4:   00021603    sra v0,v0,0x18
  4050a8:   a3c20034    sb  v0,52(s8)
  4050ac:   83c20034    lb  v0,52(s8)
  4050b0:   00000000    nop
  4050b4:   1c40ffb8    bgtz    v0,404f98 <toplevel_fnc+0x1c>
  4050b8:   00000000    nop
  4050bc:   8fc20018    lw  v0,24(s8)
  4050c0:   03c0e825    move    sp,s8
  4050c4:   8fbf003c    lw  ra,60(sp)
  4050c8:   8fbe0038    lw  s8,56(sp)
  4050cc:   27bd0040    addiu   sp,sp,64
  4050d0:   03e00008    jr  ra
  4050d4:   00000000    nop

program data


build/program-mips:     file format elf32-tradbigmips

Contents of section my_data:
 4160e0 5c5c0000                             \..    

我用 C 写成:

int toplevel_fnc(void) {
  int a = 0;
 
  while(1) {
    char c = subroutine_fnc(0);
 
    if (c <= 0) {
      return a;
    }
 
    if (c == 92) {
      a++;
      int d = write(1, "\", 2);
      if (d < 0) {
        exit(1);
      }
    } else {
      int e = write(1, &c, 1);
      if (e < 0) {
        exit(1);
      }
    }
  }
  return a;
}

int subroutine_fnc(int a) {
  char c;
   
  int b = read(a, &c, 1);
  if (b < 0) {
    exit(1);
  } else if (b == 0) {
    return 0;
  }
  return c;
}

我感到迷茫,在这里问也有点愚蠢,但我觉得我忽略了一个小错误。过去三天我一直在研究这个,但我找不到如何正确地将 MIPS 转换为 C 的解决方案。

拜托,如果有人能帮助我解决我的代码中的错误,我将非常高兴。

谢谢。

  • 汇编程序写了两个反斜杠,而Cwrite(1, "\", 2)写了一个反斜杠和一个NUL,因为\在字符串字面量中只表示一个反斜杠;你是想 write(1, "\\", 2).
  • char 是无符号的 - 这造成了另一个偏差,因为在汇编程序的某个地方,一个字节被符号扩展并随后用 bgtz 测试,而在C代码
        char c = subroutine_fnc(0);
    
        if (c <= 0)
    
    if 条件仅在 c = 0 时为真。请改用 signed char c …