将 MIPS 程序集转换为 C

Posted

技术标签:

【中文标题】将 MIPS 程序集转换为 C【英文标题】:Converting MIPS assembly to C 【发布时间】:2021-09-13 16:43:21 【问题描述】:

我正在努力将 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 的解决方案。

拜托,如果有人可以帮助我解决我的代码中的问题,我将非常高兴。

谢谢。

【问题讨论】:

有多种 MIPS 模拟器可供免费使用(例如 QtSPIM、MARS)。通过一些编辑,应该可以在其中一个模拟器中运行汇编代码,这将允许您单步执行它并查看它的行为方式。然后在调试器中单步调试您的 C 代码并比较两者。 看起来像是一个不同帐户的交叉帖子:reverseengineering.stackexchange.com/questions/27927/…。请不要那样做。另外:github.com/matt-kempster/mips_to_c "Failed to parse instruction at stdin line 3: 27bdffd8 addiu sp,sp,-40" 如果您在输入之前忘记删除地址/机器代码 hexdump 列,则会发生将其粘贴到 MIPS 中。如果您可以在二进制文件上重新运行 objdump,则可以使用 mips-...-objdump --no-show-raw-insn --no-addresses -d @Armali 抱歉,忘记添加了。查看 toplevel_fnc 的底部,它是正在寻址的数据的一部分。我还有一个 x86 列表,其中更清楚地说明了为什么使用“\\”。 @Armali 按需运行 - 生成的代码由我大学网站上的自动检查器检查。如果代码有效,我会为这项工作获得一定数量的积分。但是,系统只给了我可能的总分中的几分,并没有告诉我问题出在哪里。我已经联系了我的老师寻求帮助,他们也“不知道我的代码有什么问题”。所以,在所有尝试之后,我转向 Stack Overflow。 【参考方案1】: 汇编程序写两个反斜杠,而C write(1, "\\", 2)写一个反斜杠和一个NUL,因为字符串文字中的\\只表示一个反斜杠;你的意思是write(1, "\\\\", 2)char 是无符号的 - 这产生了另一个偏差,因为在汇编程序中的某个地方,一个字节被符号扩展,然后用 bgtz 进行测试,而在 C 代码中
    char c = subroutine_fnc(0);

    if (c <= 0)
if 条件仅在 c = 0 时为真。请改用 signed char c …

【讨论】:

根据其他评论:根据需要运行 - 生成的代码由我的 uni 网站上的自动检查器检查。如果代码有效,我会为这项工作获得一定数量的积分。但是,系统只给了我可能的总分中的几分,并没有告诉我问题出在哪里。我已经联系了我的老师寻求帮助,他们也“不知道我的代码有什么问题”。所以,在所有尝试之后,我转向 Stack Overflow,关于反斜杠,我已经回答了。 我明白了。 谢谢你,你是救世主!我真是个白痴,我当然想使用“\\\\”,而不仅仅是“\\”。与往常一样,这是一个我没有看到的愚蠢的小错误。谢谢谢谢! 这样的事情很容易错过。不客气。

以上是关于将 MIPS 程序集转换为 C的主要内容,如果未能解决你的问题,请参考以下文章

将 C 代码转换为 x86-64 位程序集?

C ++会首先转换为程序集吗?

将 C 代码转换为 x86-64 程序集

关于将程序集转换为 c 的问题——特别是 movzbl 指令的作用? [复制]

将代码转换为 Neon 程序集

循环遍历数组 MIPS 程序集