본문 바로가기
소프트웨어/컴퓨터 구조(MIPS)

[MIPS] MIPS programming 과제 - 절대 값 계산하기

by Ruas 2021. 11. 9.
728x90

오늘은 MIPS를 사용하여 절대 값 연산을하는 코드를 설명드리겠습니다.

 

해당 포스트를 진행하기에 앞서 기본적인 opcode 학습이 필요합니다.

 

 

[MIPS] MIPS programming 기본

 

[MIPS] MIPS programming 기본

opcode Artithmetic Instructions opcode 사용 방법 의미 add add $s1, $t0, $t1 $s1 = $t0 + $t1 sub sub $s1, $t0, $t1 $s1 = $t0 - $t1 mul mul $s1, $t0, $t1 $s1 = $t0 * $t1 mult mult $t0, $t1 Lo, Hi..

ruas-coding.tistory.com

 

Q. a = |c - d| 에서 정수 변수 c와 d의 차이 값 a를 구하는 프로그램을 작성하시오.

 

먼저 입력 받을 변수 c와 d를 0으로 초기화한 상태로 선언합니다.

 

    .data
c: .word 0
d: .word 0
m: .word -1
    .text

 

추가적으로 절대 값으로 변환하는 과정에서 음수를 처리해줄 변수 m도 이곳에서 선언합니다.

 

main:
    li $v0, 5
    syscall
    sw $v0, c

    li $v0, 5
    syscall
    sw $v0, d

 

다음으로 변수 c와 d에 사용자 입력을 받습니다.

이부분의 경우 다른 포스트에서도 많이 설명 드렸으니 자세한 설명은 하지 않겠습니다.

 

    lw $t0, c
    lw $t1, d

 

위에서 입력 받은 변수를 레지스터로 전송합니다.

 

    slt $s0, $t0, $t1
    beq $s0, 1, modulus
    beq $s0, 0, number

 

위 코드는 마이너스 연산을 했을 때 결과 값이 음수인지 양수인지 판단하여 처리하기 위한 시작점 입니다.

연산을 했을 때 결과가 음수로 나온다면, 절대 값으로 표현하기 위해 결과에 -1을 곱해줘야 하며,

양수일 경우 해당 과정 없이 바로 값을 출력하면 됩니다.

 

여기서 slt $s0, $t0, $t1는 $t0와 $t1의 크기를 비교하는 과정입니다.

return 값으로 0이 나오면 $t0가 $t1보다 큰 경우,

반대로 1이 나오면 $t0가 $t1보다 작은 경우를 의미합니다.

 

변수 c가 d보다 작은 경우에 음수의 결과를 얻을 수 있기 때문에 별도로 구현한  modulus 함수로 이동하며,

반대인 경우는 정상적으로 값을 출력하는 number 함수로 이동합니다.

 

modulus:
    lw $t2, m
    sub $s1, $t0, $t1
    mul $s2, $s1, $t2 
    
    move $a0, $s2
    li $v0, 1
    syscall

    li $v0, 10
    syscall

modulus 함수에서는 우선 변수 m에 저장되어 있던 -1을 레지스터로 전송합니다.

 

이후에 c-d 연산을 수행하고(sub $s1, $t0, $t1),

결과 값에 -1을 곱하여 절대 값 연산을 완료합니다(mul $s2, $s1, $t2).

 

이를 $a0 레지스터로 이동하여 출력하고,

시스템을 종료합니다.

 

number:
    sub $s1, $t0, $t1

    move $a0, $s1
    li $v0, 1
    syscall

    li $v0, 10
    syscall

 

number 함수에서는 c-d 연산 결과가 음수로 나올 수 없기 때문에 빼기 연산만 수행합니다.

이후 값을 출력하고,

시스템을 종료합니다.

 

 

 

 

아래는 전체 코드 입니다.

 

    .data
c: .word 0
d: .word 0
m: .word -1
    .text

main:
    li $v0, 5
    syscall
    sw $v0, c
    #변수 C 입력
    li $v0, 5
    syscall
    sw $v0, d
    #변수 d 입력

    lw $t0, c
    lw $t1, d
    #입력받은 변수 c,d를 레지스터로 전송

    slt $s0, $t0, $t1 #c,d를 비교해서 어떤 수가 더 큰지 확인
    beq $s0, 1, modulus #c가 더 클 경우 modulus 함수로 이동
    beq $s0, 0, number #d가 더 클 경우 number 함수로 이동

modulus:
    lw $t2, m #연산결과가 음수로 나오기 때문에 결과에 -1을 곱하여 절대값으로 변환
    sub $s1, $t0, $t1 #마이너스 연산 (c-d)
    mul $s2, $s1, $t2 #마이너스 연산 결과에 -1 곱하기
    
    move $a0, $s2
    li $v0, 1
    syscall
    #연산결과 출력

    li $v0, 10
    syscall
    #종료

number:
    sub $s1, $t0, $t1 #연산결과가 음수로 나오지 않기 때문에 마이너스 연산 진행

    move $a0, $s1
    li $v0, 1
    syscall
    #연산결과 출력

    li $v0, 10
    syscall
    #종료

이상입니다.

728x90

댓글