2016년 2월 5일 금요일

Random Value Input & Grade Generator using Mips

※ Fibonacci Sequence using Mips

  • Condition
       A >=90
90 > B >= 70
70 > C >= 50
50 > D >= 30
30 > F >= 10


  • Tool


- SPIM : Simulator of MIPS Processor (Software in order to execute assembly code


  • Instruction Set




  •  Result Screen




  •  Source Explanation


main:
 li $v0, 4
 la $a0, string
 syscall

 li $v0, 5
 syscall
콘솔창에 "seed input = " 출력하기 위해 $v0 4 저장하여 string 콘솔에 출력하는 시스템 콜을 통해 $a0레지스터에 string레이블의 주소값을 저장한다후에 system콜을 하게 되면 "seed input = " 출력된다데이터 스택공간에 string: .asciiz "seed input = " 정의 해놨다.
 li $t0, 0
 li $t1, 5
 la $t2, array
5개의 값을 랜덤으로 받기 위해 $t0 시작위치0 $t1 위치 5 (0<= <5) 이용할 것이다. $t2에는 array레이블 주소를 저장한다. $t2 이용해 랜덤한 5개의 수를 저장할 것이다.

Loop1:
 beq $t0, $t1, L1
 add $a0, $zero, $v0
$t0 $t1 같은지 비교하여($t1 고정하고 $t1 1 증가시킬 것이다.) 같게 되면 랜덤한 수가 모두 입력이 완료 되었으므로 L1레이블로 이동한다.

 addi $sp, $sp, -4
 sw $ra, 0($sp)
 jal RandomNumberGenerator
 lw $ra, 0($sp)
 addi $sp, $sp, 4
함수 호출전에 스택공간을 할당후 현재 $ra 저장된 값을 보존하기 위해 스택 공간에 저장한다. RandomNumberGenerator 함수를 호출하기위해 jal 명령어( 다음 명령어의 주소를 $ra 저장한다) 통해 RandomNumberGenerator레이블 위치로 이동한다.

 sw $v0, 0($t2)
 addi $t0, $t0, 1
 addi $t2, $t2, 4
 j Loop1
RandomNumberGenerator 함수를 빠져나온 반환된 값을 $t2 배열에 하나씩 저장할 것이다저장후 다음 값을 저장해야하므로 $t0 5 반복을 위해 1 증가 시키고 $t2 array주소는 4 더하여 다음 인덱스를 가르킨다.

L1:
랜덤한 수가 모두 입력이 완료 되었으면 L1레이블 이후로 진행 된다.

 li $t0, 0
 li $t1, 5
 la $t2, array
Loop2: 
 beq $t0, $t1, L2
$t0(5 반복하기 위해 사용할 레지스터) $t1(5) 이용하여 beq명령문을 통해 조건이 숫자가 같으면  5=5 된다면 L2레이블로 이동한다.
 lw $t3, 0($t2)
 li $v0, 1
 add $a0, $zero, $t3
 syscall
배열의 값을 뽑는 것은 ‘3 문제 전에도 많이 설명했으므로 생략하겠습니다현재 $t2 array주소가 가르키는 숫자를 시스템 콜을 이용하여 출력한다.

 slti $t4, $t3, 30 
 beq $t4, $zero, Else1
 li $t5, 'F’

 li $v0, 11
 add $a0, $zero, $t5
 syscall
slti slt 비슷하다 2번째 비교값이 상수값(imediate) 것이 차이점이다. $t3(array주소가 가르키는 값이 저장된 레지스터) 숫자 30 비교하여 $t3<30이면 $t4 1 저장된다.
beq명령어를 통해 $t4 0 같으면  30보다 크다면 Esle1레이블로 이동한다.
30미만이라면 character문자를 콘솔창에 출력하는 시스템콜($v0=11)하여 $t5 저장된 ‘F’문자를 $a0 저장하여 출력한다.

 li $v0, 11
 li $a0, '\n'
 syscall
5개의 숫자를 구분하기 위해 ‘\n’ 줄바꿈을 출력한다.

 addi $t0, $t0, 1
 addi $t2, $t2, 4

 j Loop2
$t0 1 더하고 (5 반복하기 위해) array주소는 다음 값을 불러오기 위해 4 더한다. (배열 integer값을 4바이트로 구분하기 때문이다.)
다시 반복하기 위해 Loop2레이블로 점프한다.

Else1:
30이상인 숫자가 오게 되면 Else1 레이블로 오게된다.
위와 같은 방법이므로 중요한 요점만 말하겠습니다.
 slti $t4, $t3, 50
 beq $t4, $zero, Else2
 li $t5, 'D’

 li $v0, 11
 add $a0, $zero, $t5
 syscall

 li $v0, 11
 li $a0, '\n'
 syscall

 addi $t0, $t0, 1
 addi $t2, $t2, 4

  j Loop2
50보다 작은 숫자( 30<= <50)이라면 ‘D’ 출력된다출력  Loop2 점프한다그렇지 않으면 Else2레이블로 이동한다.

Else2:
 slti $t4, $t3, 70 
 beq $t4, $zero, Else3
 li $t5, 'C'

 li $v0, 11
 add $a0, $zero, $t5
 syscall

 li $v0, 11
 li $a0, '\n'
 syscall

 addi $t0, $t0, 1
 addi $t2, $t2, 4

 j Loop2
70보다 작은 숫자( 50<= <70)이라면 ‘C’ 출력된다출력  Loop2 점프한다그렇지 않으면 Else3레이블로 이동한다.

Else3:
 slti $t4, $t3, 90
 beq $t4, $zero, Else4
 li $t5, 'B'

 li $v0, 11
 add $a0, $zero, $t5
 syscall

 li $v0, 11
 li $a0, '\n'
 syscall

 addi $t0, $t0, 1
 addi $t2, $t2, 4

 j Loop2
90보다 작은 숫자( 70<= <90)이라면 ‘B’ 출력된다출력  Loop2 점프한다그렇지 않으면 Else4레이블로 이동한다.

Else4:
li $t5, 'A'

li $v0, 11
add $a0, $zero, $t5
syscall

li $v0, 11
li $a0, '\n'
syscall

addi $t0, $t0, 1
addi $t2, $t2, 4
j Loop2
90이상( >=90)이라면 ‘A’ 출력된다출력  Loop2 점프한다.

L2:
jr $31
5번의 반복이 끝나면 L2레이블로 온다. (Loop2: beq $t0, $t1, L2)
main함수를 호출했던 곳의 바로 다음 명령어로 돌아간 프로그램은 종료된다.


-----------------------------------------------------------------------------
RandomNumberGenerator:
 li $t3, 65533
 mult $a0, $t3
 mflo $a0
 srl $a0, $a0, 5
 addi $a0, $a0, 1
 li $t3, 654
 div $a0, $t3
 mflo $a0
 li $t3, 91
 div $a0, $t3
 mfhi $a0
랜덤한 수를 만들기 위해 (처음으로 부른 함수라면 입력된 seed바로 전에 만들어진 랜덤한 수를 이용해 랜덤한 수를 만들 것이다불러온  $a0 $t3(65533)  숫자를 더하고 수를 곱하는 mult명령어를 사용한다주소는 32비트(8바이트)이므로 수를 곱하게 되면 범위를 넘어서는 값이 나온다. mfhi, mflo  이용하여 상위 8바이트나 하위 8바이트로 자른다. mflo 하위 8바이트이므로 수를 곱한 값의 하위 8바이트를 $a0 저장한다.
srl명령어를 사용하여 오른쪽으로 5비트 이동한다. 1 다시 더하고 654 div명령어를 사용하여 나누어 몫을 $a0 저장한다. div명령어는 mflo 몫을 나타내며 mfhi 나머지를 나타낸다.
랜덤한 수를 위해 아무 숫자나 가감승제 하였다이제 10~100사이의 숫자를 구하기 위해 $a0 91 나누어 나머지값(div mfhi이용) $a0 저장한다이러면 0~90까지인 범위가 된다.

 add $v0, $a0, 10
 jr $ra
0~90까지 범위의 숫자에 10 더하게 되면 10~100 숫자가 나오게 된다 숫자를 반환값에 사용할 레지스터 $v0 저장후 RandomNumberGenerator함수를 호출한 곳으로 돌아간다.

-----------------------------------------------------------------------------
.data
string: .asciiz "seed input = "
array: .word 0:5
데이터 스택공간에 "seed input = " string레이블에 저장하고 array word0:5
 6개의 4바이트 공간을 선언한다.

-----------------------------------------------------------------------------


댓글 없음:

댓글 쓰기