使用数组转换为 MIPS 汇编语言
Converting to MIPS assembly Language with arrays
不是最擅长转换,尤其是转换为 MIPS 汇编语言。
这是原始代码:
void swap(int v[], int k, int j) {
int temp;
temp = v[k];
v[k] = v[j];
v[j] = temp;
}
在一些帮助下我们设法做到了这一点,现在我需要将其转换为 MIPS 汇编代码,才刚刚完成学习 Java 仍然是菜鸟。欢迎任何帮助。
k = k << 2;
k = k + v
j = j << 2;
j = j + v
temp0 = load(k)
temp1 = load(j)
store(k) = temp1
store(j) = temp0
好的,这是 asm。它是基于上面的伪代码,但我是根据顶部的 HLL 从头开始编写的。
它是 mips ABI 一致性。因此,可以随意更改(即销毁)参数寄存器。因此,如果在循环中调用,调用者必须在每次调用前设置 a0-a3
。
# void
# swap(int v[],int k,int j)
# {
# int temp;
#
# temp = v[k];
# v[k] = v[j];
# v[j] = temp;
# }
# swap -- swap two elements in an array
#
# arguments:
# a0 -- pointer to array
# a1 -- array index "k"
# a2 -- array index "j"
#
# registers:
# t0 -- v[k]
# t1 -- v[j]
swap:
sll $a1,$a1,2 # k <<= 2 (i.e. byte offset)
addu $a1,$a1,$a0 # get address of v[k]
sll $a2,$a2,2 # j <<= 2 (i.e. byte offset)
addu $a2,$a2,$a0 # get address of v[j]
lw $t0,0($a1) # fetch v[k]
lw $t1,0($a2) # fetch v[j]
sw $t1,0($a1) # v[k] = v[j]
sw $t0,0($a0) # v[j] = v[k]
jr $ra # return
更新:
I know sll
stands for shift left. What does addu
stand for??
u
"suffix"代表unsigned。但是,不像在很多其他地方使用的那样。
有两个版本[add
]。 签名版本是add
,未签名版本是addu
。它们两者产生完全相同的结果,因为它们都进行相同的二进制补码加法。
只有的区别在于,如果加法导致溢出,add
会产生处理器异常(例如"arithmetic overflow"),但是addu
将 而不是 ——它只会换行。 sub
和下溢类似。
例如,如果寄存器中有 0x7FFFFFFF
,而您向其中加一,则会导致溢出。那是因为你从最大有符号 positive 值开始,你 add 一个给它,然后 voila 您处于最大有符号 负数 值(即 "quantum leap" 称为溢出)。
因此,当添加可能合法溢出的东西(即32位中的"wrap")时,如地址计算,最好使用无符号版本。
这是因为,在 mips 中,程序的某些部分 [code/data/stack] 可能会加载到 0x80000000 或更高位置。
例如,堆栈可能从 0x80001000
开始,如果您将足够的数据压入其中(即 $sp
寄存器随着 sub
递减),它最终会命中0x80000000
的邻域。当你 push/pop 在这个地址附近时,你会得到 overflow/underflow.
这是而不是错误——这是很自然的,并且您不希望处理器在为推送操作执行sub
时产生异常, 所以你使用 subu
[and/or immediate 形式的指令 subiu
].
如果您还没有找到它,这里有一个很好的指令集参考 [很多人都在使用]:http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html它很容易阅读,涵盖了您正在使用的大部分指令可能 need/use.
以下是 ABI 调用约定的简要概述:http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/altReg.html
不是最擅长转换,尤其是转换为 MIPS 汇编语言。
这是原始代码:
void swap(int v[], int k, int j) {
int temp;
temp = v[k];
v[k] = v[j];
v[j] = temp;
}
在一些帮助下我们设法做到了这一点,现在我需要将其转换为 MIPS 汇编代码,才刚刚完成学习 Java 仍然是菜鸟。欢迎任何帮助。
k = k << 2;
k = k + v
j = j << 2;
j = j + v
temp0 = load(k)
temp1 = load(j)
store(k) = temp1
store(j) = temp0
好的,这是 asm。它是基于上面的伪代码,但我是根据顶部的 HLL 从头开始编写的。
它是 mips ABI 一致性。因此,可以随意更改(即销毁)参数寄存器。因此,如果在循环中调用,调用者必须在每次调用前设置 a0-a3
。
# void
# swap(int v[],int k,int j)
# {
# int temp;
#
# temp = v[k];
# v[k] = v[j];
# v[j] = temp;
# }
# swap -- swap two elements in an array
#
# arguments:
# a0 -- pointer to array
# a1 -- array index "k"
# a2 -- array index "j"
#
# registers:
# t0 -- v[k]
# t1 -- v[j]
swap:
sll $a1,$a1,2 # k <<= 2 (i.e. byte offset)
addu $a1,$a1,$a0 # get address of v[k]
sll $a2,$a2,2 # j <<= 2 (i.e. byte offset)
addu $a2,$a2,$a0 # get address of v[j]
lw $t0,0($a1) # fetch v[k]
lw $t1,0($a2) # fetch v[j]
sw $t1,0($a1) # v[k] = v[j]
sw $t0,0($a0) # v[j] = v[k]
jr $ra # return
更新:
I know
sll
stands for shift left. What doesaddu
stand for??
u
"suffix"代表unsigned。但是,不像在很多其他地方使用的那样。
有两个版本[add
]。 签名版本是add
,未签名版本是addu
。它们两者产生完全相同的结果,因为它们都进行相同的二进制补码加法。
只有的区别在于,如果加法导致溢出,add
会产生处理器异常(例如"arithmetic overflow"),但是addu
将 而不是 ——它只会换行。 sub
和下溢类似。
例如,如果寄存器中有 0x7FFFFFFF
,而您向其中加一,则会导致溢出。那是因为你从最大有符号 positive 值开始,你 add 一个给它,然后 voila 您处于最大有符号 负数 值(即 "quantum leap" 称为溢出)。
因此,当添加可能合法溢出的东西(即32位中的"wrap")时,如地址计算,最好使用无符号版本。
这是因为,在 mips 中,程序的某些部分 [code/data/stack] 可能会加载到 0x80000000 或更高位置。
例如,堆栈可能从 0x80001000
开始,如果您将足够的数据压入其中(即 $sp
寄存器随着 sub
递减),它最终会命中0x80000000
的邻域。当你 push/pop 在这个地址附近时,你会得到 overflow/underflow.
这是而不是错误——这是很自然的,并且您不希望处理器在为推送操作执行sub
时产生异常, 所以你使用 subu
[and/or immediate 形式的指令 subiu
].
如果您还没有找到它,这里有一个很好的指令集参考 [很多人都在使用]:http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html它很容易阅读,涵盖了您正在使用的大部分指令可能 need/use.
以下是 ABI 调用约定的简要概述:http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/altReg.html