所以,我有一个问题,它转换了一个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操作,当它添加4到$t0时到底会发生什么,我知道如果它存储一个整数,它只会添加4到那个数字,如果我引用$sp,然后添加$sp,4意味着pop操作。我真的很困惑那部分发生了什么。
.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

最佳答案

我的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宏内部递增。

09-30 14:01
查看更多