以 mips 的形式将计算出的整数值添加到我的数组中
Adding a calculated integer value into my array in mips
当我 运行 程序时,我尝试以 mips 的形式将我的数字添加到我的数组中,但数组中唯一被填充的索引是当我的索引值 = 0 时,其他数字都显示作为 0.
编辑:这是我的完整 mips 代码和我用来翻译的代码
import java.util.Scanner;
public class PrimeDivisors {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter n: ");
int n = input.nextInt();
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
System.out.println(n + "! = " + factorial);
int[] primes = findPrimeDivisors(factorial);
largestPower(primes, n);
}
public static void largestPower(int[] primes, int n) {
System.out.println("Prime divisor\tLargest Power");
int largestPower = 0;
for (int i = 0; i < primes.length; i++) {
if (primes[i] == 0) {
break;
}
int primeNum = primes[i];
System.out.print("\t" + primeNum);
int hold = n;
while (hold > 0) {
hold /= primeNum;
largestPower += hold;
}
System.out.print("\t\t\t\t" + largestPower + "\n");
largestPower = 0;
}
}
public static int[] findPrimeDivisors(int factorial) {
int[] primes = new int[1000000];
int index = 0;
System.out.print("Prime Divisors of " + factorial + " = ");
for (int i = 2; i < factorial; i++) {
while (factorial % i == 0) {
primes[index] = i;
factorial /= i;
}
index++;
}
if(factorial > 2){
primes[index-1] = factorial;
}
for(int i = 0; i < primes.length; i++){
if(primes[i+1] == 0){
System.out.print(primes[i]);
break;
} else {
System.out.print(primes[i] + ", ");
}
}
System.out.println();
return primes;
}
}
.data
primeArray: .space 120
prompt: .asciiz "Enter n: "
prompt2: .asciiz "Prime Divisor\tLarges Power"
prompt3: .asciiz "Prime Divisors of "
comma: .asciiz ", "
equals: .asciiz " = "
period: .asciiz ".\n"
exclamation: .asciiz "! = "
tab: .asciiz "\t"
tabs: .asciiz "\t\t\t\t"
newLine: .asciiz "\n"
input_number: .space 32 #Space for user input
.text
.globl main
main:
#Print the prompt
li $v0, 4
la $a0, prompt #Address of prompt
syscall
#User Input
li $v0, 5
syscall
#Store user input into $t0
move $t0, $v0
li $t1, 0 #int i = 1
li $t2, 1 #factorial = 1
jal calculateFactorial
#print user input
li $v0, 1
move $a0, $t0
syscall
#print exclamation and equals
li $v0, 4
la $a0, exclamation
syscall
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#print period
li $v0, 4
la $a0, period
syscall
jal findPrimeDivisors
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#exit program
li $v0, 10
syscall
findPrimeDivisors:
#Print prompt3
li $v0, 4
la $a0, prompt3
syscall
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#Print equals
li $v0, 4
la $a0, equals
syscall
addi $t3, $zero, 0 #Array index = 0
li $t1, 2 #Index I=2
la $s1, primeArray
jal findPrimes
#exit program
li $v0, 10
syscall
#input={$t0} i={$t1}, factorial={$t2}, arrayIndex={$t3}
findPrimes: #outer loop
bgt $t1, $t2 exitLoop
sw $ra, ($sp)
jal innerLoop #innerLoop
lw $ra, ($sp)
addi $t1, $t1, 2 #increment outer loop by 2
addi $t3, $t3, 4 #increment array index in outside loop
j findPrimes
#remainder = ${t4}
innerLoop:
bne $t4, 0, exitLoop #Break if remainder is not equal
sw $t1, primeArray($t3) #Store value of I into array
div $t2, $t2, $t1 #Factorial = Factorial / I
mfhi $t4
j innerLoop
#input={$t0} i={$t1}, factorial={$t2}
calculateFactorial:
beq $t1, $t0, exitLoop
addi $t1, $t1, 1
mul $t2, $t1, $t2
j calculateFactorial
exitLoop:
jr $ra
如果我无法访问任何超过 0 的索引,请提供任何帮助。
您永远不会初始化 $t4
。因此,bne $t4, 0, exitLoop
第一次落空,因为 $t4
被模拟器初始化为零。此后,它被“初始化”为它采用的最后一个值,该值是故意的 non-zero 值,因为这是内部循环退出的唯一方式。
该内部循环也不会修改 $t3
,因此如果它有多个值,它会将它们全部存储到同一个地方。
从根本上说,您犯了一个错误,即假设可以使用 high-level 语言代码,但在翻译成汇编的过程中却选择偏离该代码。这始终是一个容易出错的尝试。如果您想进行更改(例如改进或优化),请先在 high-level 或伪代码中进行更改,然后对其进行测试以确保其有效。然后忠实地把伪代码转录成汇编。
在程序集中,您引入了一个附加函数,并将部分伪代码循环移到了这些新函数中,同时将同一循环的其他部分留在了外部。这不是基于逻辑等价的转换。因此,没有理由期望汇编代码的工作方式与 pseudo/Java 代码相同。虽然您可能认为引入较小的函数来完成部分工作是一种逻辑转换,但您错误地将主循环的工作分配给了新函数及其调用者。
您有一些违反调用约定的行为,但如果它在其他方面有效,那对您来说可能不是问题。
当我 运行 程序时,我尝试以 mips 的形式将我的数字添加到我的数组中,但数组中唯一被填充的索引是当我的索引值 = 0 时,其他数字都显示作为 0.
编辑:这是我的完整 mips 代码和我用来翻译的代码
import java.util.Scanner;
public class PrimeDivisors {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter n: ");
int n = input.nextInt();
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
System.out.println(n + "! = " + factorial);
int[] primes = findPrimeDivisors(factorial);
largestPower(primes, n);
}
public static void largestPower(int[] primes, int n) {
System.out.println("Prime divisor\tLargest Power");
int largestPower = 0;
for (int i = 0; i < primes.length; i++) {
if (primes[i] == 0) {
break;
}
int primeNum = primes[i];
System.out.print("\t" + primeNum);
int hold = n;
while (hold > 0) {
hold /= primeNum;
largestPower += hold;
}
System.out.print("\t\t\t\t" + largestPower + "\n");
largestPower = 0;
}
}
public static int[] findPrimeDivisors(int factorial) {
int[] primes = new int[1000000];
int index = 0;
System.out.print("Prime Divisors of " + factorial + " = ");
for (int i = 2; i < factorial; i++) {
while (factorial % i == 0) {
primes[index] = i;
factorial /= i;
}
index++;
}
if(factorial > 2){
primes[index-1] = factorial;
}
for(int i = 0; i < primes.length; i++){
if(primes[i+1] == 0){
System.out.print(primes[i]);
break;
} else {
System.out.print(primes[i] + ", ");
}
}
System.out.println();
return primes;
}
}
.data
primeArray: .space 120
prompt: .asciiz "Enter n: "
prompt2: .asciiz "Prime Divisor\tLarges Power"
prompt3: .asciiz "Prime Divisors of "
comma: .asciiz ", "
equals: .asciiz " = "
period: .asciiz ".\n"
exclamation: .asciiz "! = "
tab: .asciiz "\t"
tabs: .asciiz "\t\t\t\t"
newLine: .asciiz "\n"
input_number: .space 32 #Space for user input
.text
.globl main
main:
#Print the prompt
li $v0, 4
la $a0, prompt #Address of prompt
syscall
#User Input
li $v0, 5
syscall
#Store user input into $t0
move $t0, $v0
li $t1, 0 #int i = 1
li $t2, 1 #factorial = 1
jal calculateFactorial
#print user input
li $v0, 1
move $a0, $t0
syscall
#print exclamation and equals
li $v0, 4
la $a0, exclamation
syscall
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#print period
li $v0, 4
la $a0, period
syscall
jal findPrimeDivisors
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#exit program
li $v0, 10
syscall
findPrimeDivisors:
#Print prompt3
li $v0, 4
la $a0, prompt3
syscall
#print factorial value
li $v0, 1
move $a0, $t2
syscall
#Print equals
li $v0, 4
la $a0, equals
syscall
addi $t3, $zero, 0 #Array index = 0
li $t1, 2 #Index I=2
la $s1, primeArray
jal findPrimes
#exit program
li $v0, 10
syscall
#input={$t0} i={$t1}, factorial={$t2}, arrayIndex={$t3}
findPrimes: #outer loop
bgt $t1, $t2 exitLoop
sw $ra, ($sp)
jal innerLoop #innerLoop
lw $ra, ($sp)
addi $t1, $t1, 2 #increment outer loop by 2
addi $t3, $t3, 4 #increment array index in outside loop
j findPrimes
#remainder = ${t4}
innerLoop:
bne $t4, 0, exitLoop #Break if remainder is not equal
sw $t1, primeArray($t3) #Store value of I into array
div $t2, $t2, $t1 #Factorial = Factorial / I
mfhi $t4
j innerLoop
#input={$t0} i={$t1}, factorial={$t2}
calculateFactorial:
beq $t1, $t0, exitLoop
addi $t1, $t1, 1
mul $t2, $t1, $t2
j calculateFactorial
exitLoop:
jr $ra
如果我无法访问任何超过 0 的索引,请提供任何帮助。
您永远不会初始化 $t4
。因此,bne $t4, 0, exitLoop
第一次落空,因为 $t4
被模拟器初始化为零。此后,它被“初始化”为它采用的最后一个值,该值是故意的 non-zero 值,因为这是内部循环退出的唯一方式。
该内部循环也不会修改 $t3
,因此如果它有多个值,它会将它们全部存储到同一个地方。
从根本上说,您犯了一个错误,即假设可以使用 high-level 语言代码,但在翻译成汇编的过程中却选择偏离该代码。这始终是一个容易出错的尝试。如果您想进行更改(例如改进或优化),请先在 high-level 或伪代码中进行更改,然后对其进行测试以确保其有效。然后忠实地把伪代码转录成汇编。
在程序集中,您引入了一个附加函数,并将部分伪代码循环移到了这些新函数中,同时将同一循环的其他部分留在了外部。这不是基于逻辑等价的转换。因此,没有理由期望汇编代码的工作方式与 pseudo/Java 代码相同。虽然您可能认为引入较小的函数来完成部分工作是一种逻辑转换,但您错误地将主循环的工作分配给了新函数及其调用者。
您有一些违反调用约定的行为,但如果它在其他方面有效,那对您来说可能不是问题。