C 到 MIPS 转换

C to MIPS translate

这里给了我一个试题,我部分解决了但没有完全理解 为什么在这里使用volatile?和缺失的表达 我必须 switches >>8。 说到翻译我有点困难。

八个开关被内存映射到内存地址0xabab0020,其中 最低有效位(索引 0)表示开关编号 1,索引为 7 的位 表示开关编号 8。位值 1 表示开关打开,并且 0 表示关闭。写下缺失的 C 代码表达式,这样 如果 8 号拨动开关关闭,则 while 循环退出。

 volatile int * switches = (volatile int *) 0xabab0020;
 volatile int * leds = (volatile int *) 0xabab0040;
 while(/* MISSING C CODE EXPRESSION */){
   *leds = (*switches >> 4) & 1;
}

将上面的完整 C 代码翻译成 MIPS 汇编代码,包括缺少的 C 代码表达式。不允许使用伪指令。

volatile 限定符向 C 编译器表明地址 switchesleds 处的数据可以被系统中的另一个代理更改。如果没有 volatile 限定符,编译器将被允许优化对这些变量的引用。

问题描述说循环应该 运行 而 *switches 的位 7 已设置,即:while (*switches & 0x80 != 0)

翻译代码留作 reader 的练习。

volatile int * switches = (volatile int *) 0xabab0020;
volatile int * leds = (volatile int *) 0xabab0040;
  while((*switches >> 8) & 1){
    *leds = (*switches >> 4) & 1;
}

到 mips

     lui   $s0,0xabab    #load the upper half
     ori   $s0,0x0020

     lui   $s1,0xabab
     ori   $s1,0x0040
while:
     lw    $t0,0x20($s0)
     srl   $t0,$t0,8     #only the 8th bit is important
     andi  $t0,$t0,1     # clear other bit keep the LSB
     beq   $t0,[=11=], done
     lw    $t1,0x40($s1)
     srl   $t1,$t1,4
     andi  $t1,$t1,1
     sw    $t1,0x40($s1) 
     j     while
done:
     sw    $t0,0x20($s0)  

没有 volatile 你的代码可以被编译器合法地解释为:

int * switches = (volatile int *) 0xabab0020;
int * leds = (volatile int *) 0xabab0040;
*leds = (*switches >> 4) & 1;
while(/* MISSING C CODE EXPRESSION */){
}