我无法从MIPS问题中了解部分代码

时间:2018-12-26 20:04:39

标签: c mips

因此,我遇到了一个问题,该问题会转换一个C程序,该程序使用参数数目可变的函数来计算n个数字的和。

#include<stdarg.h>
  int sum(int n, ...){
    int i,s;
    va_list l;
    va_start(l,n);
    s=0;
    for(i=0;i<n;++i) s+=va_arg(l,int);
    va_end(l);
    return s;
  }
  int s;
  void main(){
    s=sum(3,1,2,3);  
    s=sum(2,10,20);
  }

这里是MIPS代码(忽略注释),但是我不明白bge下面的部分,特别是$ t0操作,当它向$ t0加4时会发生什么,我知道如果它存储一个整数它只会在该数字上加上4,如果我指的是$ sp,然后加上$ sp,则4表示弹出操作。我对那部分正在发生的事情感到非常困惑。

.data
  s: .space 4
.text
main:
  subu $sp,16   # incarcam parametrii, conform conventiei C
  li $t0,3
  sw $t0,12($sp)
  li $t0,2
  sw $t0,8($sp)
  li $t0,1
  sw $t0,4($sp)
  li $t0,3
  sw $t0,0($sp)
  jal sum      # functia returneaza in $v0
  addu $sp,16    # descarcam atatia par. cati am incarcat (adica 4 parametri)
  sw $v0,s       # val. ret. este in $v0
    # acum s contine 6
  subu $sp,12
  li $t0,20
  sw $t0,8($sp)
  li $t0,10
  sw $t0,4($sp)
  li $t0,2
  sw $t0,0($sp)
  jal sum
  addu $sp,12     # acum am incarcat doar 3 par., deci descarc doar 3 par.
  sw $v0,s
    # acum s contine 30
li $v0,10
syscall
sum:   # primeste o stiva de forma $sp:(n)()()()...
  subu $sp,16      # rezerv loc pt. salvat $fp si pentru i,s,l din functie
  sw $fp,12($sp)
  addiu $fp,$sp,12
    # acum stiva este $sp:(l)(s)(i)$fp:($fp v)(n)()()()...
  addu $t0,$fp,8
  sw $t0,-12($fp)  # va_start(l,n); avem $sp:(l)(s)(i)$fp:($fp v)(n)l:()()...
  sw $zero,-8($fp) # s=0
  sw $zero,-4($fp) # i=0
  sum_et1:
  lw $t0,-4($fp)
  lw $t1,4($fp)
  bge $t0,$t1,sum_et2  # daca i>=n iesim
    lw $t0,-12($fp)
    addu $t0,4           # 4 este sizeof(int)
    sw $t0,-12($fp)
    lw $t0,-4($t0)       # 4 este sizeof(int)
    lw $t1,-8($fp)
    add $t1,$t1,$t0
    sw $t1,-8($fp)       # s+=va_arg(i,int)
    lw $t0,-4($fp)
    add $t0,1
    sw $t0,-4($fp)       # ++i
    b sum_et1
  sum_et2:
    # in aceasta implementare nu avem ce executa pentru va_end(l)
  lw $v0,-8($fp)
  lw $fp,0($fp)
  addu $sp,16
jr $ra

1 个答案:

答案 0 :(得分:0)

我的MIPS组件非常生锈,但看起来:

lw $t0,-12($fp)   # load va_list l
addu $t0,4        # increment l to the next int argument
sw $t0,-12($fp)   # store l

lw $t0,-4($t0)    # load the argument pointed to by l (still in $t0)
lw $t1,-8($fp)    # load sum
add $t1,$t1,$t0   # add the argument to sum
sw $t1,-8($fp)    # store sum

lw $t0,-4($fp)    # load i
add $t0,1         # increment i by 1
sw $t0,-4($fp)    # store i

我认为令人困惑的部分是va_list l内部包含一个指针,并且在va_arg宏内递增。