당신은 잘못 .word
지시어를 사용했다 :
myArray: .word 256
이것은 하지 256 개 요소 배열을 정의 않습니다. 스칼라 단어의 초기 값은 256으로 정의됩니다. 배열의 크기는 4 바이트입니다.
배열에 처음 저장 한 후에는 (예 : 정의되지 않은 동작 C 언어로) 끝까지 씁니다.
대답에서 myArray
을 .data
섹션 끝으로 옮겼습니다. 그러나 이것은 이 아니며 수정 사항입니다. 단지 문제를 "넘어서"말입니다. 그리고 주문이 myArray | char
인 경우 myArray
의 두 번째 요소에는 가비지 데이터가 포함됩니다.
배열을 정의하는 올바른 방법은 .space
지시문을 사용하는 것입니다. 지정된 수의 바이트을 예약합니다. 그래서, myArray
에 대한 올바른 정의는 다음과 같습니다
myArray: .space 1024
char
배열은 비슷한 문제가 있었다, 그러나 당신은 "운도 참 좋아."
버그도 몇 가지 더 있습니다. 특히, "-1"수표는 전혀 효과가 없었다면 약했다.
나는 프로그램의 세 가지 버전을 만들었습니다. 주석이 달린 버전. 두 번째는 정리되고 고정됩니다. 세 번째는 사용자 입력을 얻기 위해 다른 syscall
을 사용하기 때문에 조금 더 간단하고, 더 일반적이며, 더 효율적입니다.
# switch to the Data segment
.data
# global data is defined here
# NOTE/BUG: this defines a _single_ 32 bit word [with initial value of 256]
# and _not_ an array with 256 elements
# as it is, myArray is only 4 bytes long
myArray: .word 256
# NOTE/BUG: this has similar problems to above but you luck out because
# it defines an area of length 4 by virtue of the .word directive and _not_
# the 4
char: .word 4
sp: .asciiz " "
cr: .asciiz "\n"
error_string: .asciiz "\ONE DOES NOT SIMPLY WALK INTO MORDOR."
array_input: .asciiz "\Please type a digit. Press enter after each. End array with -1 input.\n"
# NOTE/BUG: this string is incorrect for its intended use below
# NOTE/BUG: this isn't used
neg_one: .asciiz "\1-"
# switch to the Text segment
.text
.globl main
# the rest of the main program goes here
main:
# NOTE/BUG: this is a poor way to initialize this. use "li" or "lw" instead
# but also see below
# NOTE/BUG: manually compensating for little endian is tedious
lui $s7,0x000a # set first half of $s7
ori $s7,$s7,0x312d # set $s7 to compare with beq and exit input, $s7 = -1 now.
# NOTE/BUG: this has _no_ effect
addi $t3,$t3,0 # set counter for decrementing array later
la $s1,myArray # set base address of array to $s1
# NOTE/BUG: although not a bug, this should be part of the loop
la $a0,array_input
jal Print_string
input_loop:
la $a0,char
li $a1,4
jal Input # prompt user for digit input
lb $t1,char
# NOTE/BUG: this is a weak way to check for -1
lw $t2,char # store char from buffer into t1 (does this strip newline?)
beq $t2,$s7,begin_sort # branch if input is equivalent to -1
blt $t1,48,error # check if char is not a digit (ascii<'0')
bgt $t1,57,error # check if char is not a digit (ascii>'9')
addi $t1,$t1,-48
sw $t1,0($s1) # store char into array
move $a0,$t1
jal Print_integer # print number that was input
la $a0,cr
jal Print_string # print newline char
addi $s1,$s1,4 # increment array address
addi $t3,$t3,1 # increment array counter
j input_loop # jump back up when -1 not entered
begin_sort:
# NOTE/BUG: this _must_ be "jal" and _not_ "Jal"
# NOTE/BUG: this should just be "j" or just move the "Exit" code here
Jal Exit
error:
la $a0,error_string
li $v0,4
syscall
j input_loop
.globl Input
# gets a string from user into register
Input:
addi $v0,$zero,8
syscall # calls for input
jr $ra
.globl Print_integer
# print the integer in register a0. Loading one into $v0 from addi makes syscall print
Print_integer:
addi $v0,$zero,1
syscall
jr $ra
.globl Print_string
# print the string whose starting address is in register a0
Print_string:
addi $v0,$zero,4
syscall
jr $ra
.globl Exit
# end the program, no explicit return status
Exit:
addi $v0,$zero,10
syscall
jr $ra
다음
은 위 작업 청소 버전입니다 : 여기
은 주석 버전 [용서하십시오 무상 스타일 정리]입니다. 가장 좋은 방법이해야 할 것을 참고 "-1"검사는 줄 바꿈을 제거하고
strcmp
기능을 구현하는 것입니다,하지만 난 한 간단하게 뭔가 위의 프로그램은 여전히에 제한을 앓고
# switch to the Data segment
.data
# global data is defined here
myArray: .space 1024
eArray:
char: .space 80
echar:
sp: .asciiz " "
cr: .asciiz "\n"
error_string: .asciiz "\ONE DOES NOT SIMPLY WALK INTO MORDOR."
array_input: .asciiz "\Please type a digit. Press enter after each. End array with -1 input.\n"
# switch to the Text segment
.text
.globl main
# the rest of the main program goes here
main:
la $s1,myArray # set base address of array to $s1
la $s2,eArray # get end of array
input_loop:
# prompt user
la $a0,array_input
jal Print_string
# read in user's response
# NOTE: unless you are _required_ to decode the number yourself, using
# syscall 5 (read integer) is _much_ simpler
la $a0,char
la $a1,echar
subu $a1,$a1,$a0
jal Input # prompt user for digit input
# check for -1 on input
lb $t2,0($a0) # is first char "-"?
bne $t2,0x2D,not_negone # no, fly
lb $t2,1($a0) # is second char "1"?
bne $t2,0x31,not_negone # no, fly
lb $t2,2($a0) # is third char "\n"?
beq $t2,0x0A,begin_sort # yes, fly
not_negone:
lb $t1,0($a0)
blt $t1,48,error # check if char is not a digit (ascii<'0')
bgt $t1,57,error # check if char is not a digit (ascii>'9')
addi $t1,$t1,-48
sw $t1,0($s1) # store char into array
move $a0,$t1
jal Print_integer # print number that was input
la $a0,cr
jal Print_string # print newline char
addi $s1,$s1,4 # increment array address -- over edge?
blt $s1,$s2,input_loop # no, loop
begin_sort:
j Exit
error:
la $a0,error_string
li $v0,4
syscall
j input_loop
# gets a string from user into register
Input:
li $v0,8
syscall # calls for input
jr $ra
# print the integer in register a0. Loading one into $v0 from addi makes syscall print
Print_integer:
li $v0,1
syscall
jr $ra
# print the string whose starting address is in register a0
Print_string:
li $v0,4
syscall
jr $ra
# end the program, no explicit return status
Exit:
li $v0,10
syscall
숫자 입력은 한 자리 숫자 만 가능합니다. 일반적인 해결책은 atoi
에 해당하는 것을 구현하는 것입니다.
하지만, 당신이
syscall
# 5 정수 읽기]를 사용하여, 자신의 번호를 구문 분석을 할을 필요하지
인 경우는 훨씬 간단 정수를 허용하고, 대부분의 MIPS 프로그램을 사용하는 것입니다. # switch to the Data segment
.data
# global data is defined here
myArray: .space 1024
eArray:
sp: .asciiz " "
cr: .asciiz "\n"
error_string: .asciiz "\ONE DOES NOT SIMPLY WALK INTO MORDOR."
array_input: .asciiz "\Please type a number. Press enter after each. End array with -1 input.\n"
# switch to the Text segment
.text
.globl main
# the rest of the main program goes here
main:
la $s1,myArray # set base address of array to $s1
la $s2,eArray # get end of array
input_loop:
# prompt user
la $a0,array_input
jal Print_string
# read in user's response
li $v0,5
syscall
move $t1,$v0
# check for -1 on input
bltz $t1,begin_sort
sw $t1,0($s1) # store char into array
move $a0,$t1
jal Print_integer # print number that was input
la $a0,cr
jal Print_string # print newline char
addi $s1,$s1,4 # increment array address -- over edge?
blt $s1,$s2,input_loop # no, loop
begin_sort:
j Exit
error:
la $a0,error_string
li $v0,4
syscall
j input_loop
# gets a string from user into register
Input:
li $v0,8
syscall # calls for input
jr $ra
# print the integer in register a0. Loading one into $v0 from addi makes syscall print
Print_integer:
li $v0,1
syscall
jr $ra
# print the string whose starting address is in register a0
Print_string:
li $v0,4
syscall
jr $ra
# end the program, no explicit return status
Exit:
li $v0,10
syscall
죄송합니다. 그러나 이것은 실제로 버그 수정 사항이 아닙니다. 왜 내 대답을 참조하십시오. –