我的MIPS32数组赋值代码是否正确?及内存与传参疑问
MIPS快速排序主函数疑问解答
我正在编写快速排序的MIPS代码,主函数需要先读取用户输入的整数N(数组元素个数),再读取N个元素存入数组。由于暂未掌握动态分配内存的方法,预分配了大小为Nmax*4的arrayA数组,仅填充前N个元素。现有以下疑问及对应解答:
疑问1:arrayA的地址存储是否正确?
是正确的:
- 代码中
la $s1, arrayA指令正确将arrayA的基地址加载到寄存器$s1中,这是MIPS中加载全局变量地址的标准方式。 - 存储元素时使用的
sw $v0, arrayA($t0)是MIPS的位移寻址方式,其中arrayA会被汇编器解析为数组的基地址,加上$t0中存储的字节偏移量(每次递增4,对应int类型的字节长度),能准确定位到数组的对应元素位置。
疑问2:输入元素存入数组的流程是否正确?
流程是正确的:
- 初始化$t0为0(代表数组的字节偏移量,对应C代码中的索引i,因int占4字节,$t0 = i*4),$t1为N(剩余需要输入的元素个数)。
- 循环中通过
li $v0, 5调用系统读入整数,将结果存入$v0。 - 用
sw $v0, arrayA($t0)将读入的值存入数组对应位置。 - 更新偏移量$t0 +=4、剩余计数$t1 -=1,直到$t1为0时跳出循环。
注:C代码中scanf("%d\n")的\n可以省略,不过MIPS的syscall 5会自动跳过空白字符(包括换行、空格),因此不会影响输入逻辑。
疑问3:将数组传入其他函数时,需在调用者中把基地址加载到参数寄存器,还是在被调用者中直接访问arrayA即可?
两种方式都可行,但推荐在调用者中将基地址加载到参数寄存器,原因如下:
- 符合MIPS的函数调用ABI规范:通常使用$a0-$a3作为参数寄存器,调用者将数组基地址、元素个数等参数传入这些寄存器,被调用者通过参数寄存器访问数组。比如调用快速排序函数时,可在main中执行
move $a0, $s1(将arrayA基地址传入$a0)、move $a1, $s0(将N传入$a1),再执行jal quicksort。 - 降低耦合性:如果被调用者直接访问全局的arrayA,那么该函数只能处理这一个数组,复用性极差;通过参数传递地址,函数可以处理任意数组,扩展性更好。
附:原始代码
C语言骨架代码
int main() { int N; scanf("%d\n", &N); // will be the first line, will tell us the number of inputs we will get int i=0, A[N]; int n = N; // Loop to enter the values to be sorted into an array we have made A[]. the values are entered as a1, a2.... and so on. while(n!=0) { scanf("%d\n", &A[i]); i++; n--; } }
MIPS代码
#PROGRAM : QuickSort .data prompt : .asciiz "Number of integers : " .align 4 arrayA : .space 40000 .text main: la $a0, prompt li $v0, 4 syscall # print the prompt asking the user for array length input li $v0, 5 # $v0 holds the value of N(no of elements to be given as input, as given by the user) syscall addi $s0, $v0, zero # move the value stored in $v0(which holds the number of elements in the array) to the register $s0 li $t0, 0 # code to initialise variable i(index of array), and set it's value as 0 la $s1, arrayA # base address of the array A is loaded onto the register $s1 move $t1, $s0 # the value of N(which is stored in $s0) is also stored in the register $t1 now # code to read the number of registers to be input by the user L1: beq $t1, $zero, outL1 # branch to the outL1 if the value of $t1(which holds value of n(=N)) is equal to 0 li $v0, 5 syscall # input value of the element taken sw $v0, arrayA($t0) # assign the value input by the user to the respective element in the array in memory addi $t0, $t0, 4 # add 4(no of bytes used up) to the index of the array addi $t1, $t1, -1 # n = n-1 (n is in $t1 and is equal to the number of elements the user want to input) j L1 # go to the start of the loop L1 outL1: # exited the first while loop for entering the values into the array A
内容的提问来源于stack exchange,提问作者user202004
相关产品推荐
相关产品推荐

