본문 바로가기

Programming/Assembly Language

[MIPS] QtSpim 예제 7 - 중첩 반복문(구구단)

  • 사용 opcode : lw, beq, move, li, la, mul, add, j, bne
  • 사용 system call : 1, 4, 10

1. 문제


2단 ~ 9단까지 구구단을 출력해라.

 

예시)

        2×1=2 

        2×2=4 

 

 

2. 정답


.data
  n : .word 2
  i : .word 1
  txt1 : .asciiz " X "
  txt2 : .asciiz " = " 
  txt3 : .asciiz "\n"

.text

main : 

  lw $s0, n
  lw $s1, i

loop :

  beq $s1, 10, loop2  
  move $a0, $s0 
  li $v0, 1
  syscall  

  la $a0, txt1       
  li $v0, 4
  syscall

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

  la $a0, txt2     
  li $v0, 4
  syscall
  
  mul $s2, $s0, $s1  
  move $a0, $s2
  li $v0, 1
  syscall

  la $a0, txt3    
  li $v0, 4
  syscall
 
 add $s1, $s1, 1  
  j loop

loop2 :
  li $s1, 1           
  add $s0, $s0, 1  
  bne $s0, 10, loop   

  li $v0, 10
  syscall

 

 

3. 풀이


2 × 1 = 2 형태로 표현하기 위해 필요한 변수를 정의합니다. 

 

.data
  n : .word 2           # n x i
  i : .word 1           
  txt1 : .asciiz " X "  # X
  txt2 : .asciiz " = "  # =
  txt3 : .asciiz "\n"   # 줄바꿈

 

 

 

n과 i의 값을 사용하기 위해 레지스터에 로드해줍니다.

 

main : 

  lw $s0, n
  lw $s1, i

 

 

구구단을 출력해야하기 때문에 총 두 개의 반복문이 필요합니다. 각 단별로 총 9개의 곱셈식을 출력해야하기 때문에 n(2단~9단)을 증가시킬 반복문과 i(1~9)를 증가시킬 반복문이 필요합니다. 아래코드는 loop와 loop2를 사용해 구현하였습니다.

 

 

loop는 i의 값을 증가시키기 위한 반복문입니다. i의 값을 1부터 9까지 증가시킴으로써 총 9개의 곱셈식을

출력합니다. 특정 단의 곱셈식 9개를 모두 출력한 후에는 다음 단으로 넘어가야 합니다. 즉, n을 증가시키는 loop2로 넘어가야한다는 의미입니다. beq opcode를 사용해 i의 값이 10이 되는 순간 loop2로 넘어가도록 해줍니다.

 

loop :

  beq $s1, 10, loop2  # i=10이라면 루프 종료
  move $a0, $s0       # n 출력
  li $v0, 1
  syscall  

  la $a0, txt1        # X 출력
  li $v0, 4
  syscall

  move $a0, $s1       # i 출력
  li $v0, 1
  syscall

  la $a0, txt2        # = 출력
  li $v0, 4
  syscall
  
  mul $s2, $s0, $s1   # n x i  출력
  move $a0, $s2
  li $v0, 1
  syscall

  la $a0, txt3        # 줄바꿈
  li $v0, 4
  syscall
 
 add $s1, $s1, 1      # i=i+1
  j loop

 

 

loop2는 n의 값을 증가시키기 위한 반복문입니다. n의 값을 1씩 증가시킴으로써 다음 단으로 넘어갑니다. i의 값을 1로 초기화하고 n+1을 수행한 후 loop로 되돌아갑니다. 이때, n이 10이라면 구구단을 이미 모두 출력했기 때문에 loop로 돌아가지 않고 프로그램을 종료합니다.

 

loop2 :
  li $s1, 1           # i 초기화
  add $s0, $s0, 1     # n=n+1
  bne $s0, 10, loop   # n!=10 이면 루프 다시 시작

  li $v0, 10
  syscall

 

 

4. c++ 코드로 표현


#include <stdio.h>

int main() {

	int n = 2;
	int i = 1;

	for (n; n < 10; n++) {

		for (i; i < 10; i++) {
			printf("%d x %d = %d\n", n, i, n*i);
		}

		i = 1;
	}
}