Assembly 我不知道';我不理解这个程序的输出
我在汇编中有这段代码,当输入和整数如“131071”时,输出是1和-1。我试图理解为什么,我理解它是将整数一分为二,但为什么我会得到这个结果Assembly 我不知道';我不理解这个程序的输出,assembly,mips,Assembly,Mips,我在汇编中有这段代码,当输入和整数如“131071”时,输出是1和-1。我试图理解为什么,我理解它是将整数一分为二,但为什么我会得到这个结果 .text .globl main main: #main has to be a global label addu $s7, $0, $ra #save the return address in a global register loop:
.text
.globl main
main: #main has to be a global label
addu $s7, $0, $ra #save the return address in a global register
loop:
# Read in the word to split
.data
.globl message1
message1: .asciiz "\nEnter an integer value: " #string to print
.text
li $v0, 4 # print_str
la $a0, message1 # takes the address of string as an argument
syscall
li $v0, 5 # read_int
syscall
beqz $v0, exit1 # terminate on 0 value
add $a0, $v0, $0 # move $v0 to $a0
jal halves # call the function halves
add $s0, $v0, $0 # save first return value
add $s1, $v1, $0 # save second return value
# Now print out halves
.data
.globl message2
message2: .asciiz "\nThe halves are: " #string to print
.text
li $v0, 4 # print_str
la $a0, message2 # takes the address of string as an argument
syscall
li $v0, 1 # print_int
add $a0, $0, $s0 # put value to print in $a0
syscall
.data
.globl message3
message3: .asciiz " and " # string to print
.text
li $v0, 4 # print_str
la $a0, message3 # takes the address of string as an argument
syscall
li $v0, 1 # print_int
add $a0, $0, $s1 # put value to print in $a0
syscall
j loop # get another word
exit1:
.data
.globl message4
message4: .asciiz "\nProgram terminated. " #string to print
.text
li $v0, 4 # print_str
la $a0, message4 # takes the address of string as an argument
syscall
# Usual stuff at the end of the main
addu $ra, $0, $s7 # restore the return address
jr $ra # return to the main program
add $0, $0, $0 # nop
# subroutine halves
.globl halves
halves:
sub $sp, $sp, 8 # make space on the stack for two items
sw $s1, 4($sp) # save register $s1
sw $s0, 0($sp) # save register $s0
add $s0, $a0, $0 # register $s0 contains the word to split
sra $v0, $s0, 16 # extract the upper half
add $s1, $0, 0xffff # create a mask
and $s1, $s1, $s0 # extract the lower half
sll $s1, $s1, 16 # ensure sign extention
sra $v1, $s1, 16 # return to position
lw $s0, 0($sp) # restore register $s0
lw $s1, 4($sp) # restore register $s1
add $sp, $sp, 8 # adjust the stack before the return
jr $ra # return to the calling program
没有错误,我只是不理解输出。例如,如果我使用像2000这样的数字,结果是0和2000哪个部分不清楚?它只是打印
x/65536
和x%65536
。-1
实际上是65535
但是符号扩展了。halves
写得非常低效!您可以只使用$t0
和$t1
而不是保存/恢复$s0..1
。而0xFFFF
可以作为和(16位零扩展)的立即数进行编码,但讽刺的是,不能作为添加的立即数(16位符号扩展)。如果你无论如何都要向左/向右移动,你也可以这样做,不必费心去做,就可以去掉高位。因此,函数可以是4条指令(3个移位和jr$ra
)。