Post

[CA] Chapter 3-2: Logical Operations-EXERCISE

[CA] Chapter 3-2: Logical Operations-EXERCISE

Computer Architecture 공부

앞에서 공부한 Decision-Making Instruction, Comparsion Instruction을 가지고 예시 코드를 해석해 보자

Switch Statement 구현

C/C++ 예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
switch (value) {
    case 1:
        // value가 1일 때 실행할 코드
        break;
    case 2:
        // value가 2일 때 실행할 코드
        break;
    case 3:
        // value가 3일 때 실행할 코드
        break;
    default:
        // 어떤 case에도 해당하지 않을 때 실행할 코드
}

어셈블리 코드 예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 데이터 섹션: 출력할 메시지 정의
.data
msg_case_1: .asciiz "Case 1 selected\n"
msg_case_2: .asciiz "Case 2 selected\n"
msg_case_3: .asciiz "Case 3 selected\n"
msg_default: .asciiz "Default case selected\n"

# 코드 섹션
.text
.globl main

main:
    # 스위치 변수 로드 (예: value = 2)
    li $t0, 2        # 스위치 변수 값 설정
    
    # 각 케이스 값 로드
    li $t1, 1        # Case 1 값
    li $t2, 2        # Case 2 값
    li $t3, 3        # Case 3 값
    
    # 케이스 1 비교
    beq $t0, $t1, case_1    # value == 1 ?
    
    # 케이스 2 비교
    beq $t0, $t2, case_2    # value == 2 ?
    
    # 케이스 3 비교
    beq $t0, $t3, case_3    # value == 3 ?
    
    # 기본 케이스 (모든 비교 실패)
    j default_case
    
case_1:
    # 케이스 1 처리 코드
    li $v0, 4               # 문자열 출력 시스템 콜
    la $a0, msg_case_1      # 메시지 주소 로드
    syscall
    j end_switch            # 스위치 문 종료
    
case_2:
    # 케이스 2 처리 코드
    li $v0, 4               # 문자열 출력 시스템 콜
    la $a0, msg_case_2      # 메시지 주소 로드
    syscall
    j end_switch            # 스위치 문 종료
    
case_3:
    # 케이스 3 처리 코드
    li $v0, 4               # 문자열 출력 시스템 콜
    la $a0, msg_case_3      # 메시지 주소 로드
    syscall
    j end_switch            # 스위치 문 종료
    
default_case:
    # 기본 케이스 처리 코드
    li $v0, 4               # 문자열 출력 시스템 콜
    la $a0, msg_default     # 메시지 주소 로드
    syscall
    
end_switch:
    # 스위치 문 이후 코드
    li $v0, 10              # 프로그램 종료 시스템 콜
    syscall
  • $t0 = 2인 경우:
    1. beq $t0, $t1, case_1 - $t0(2)와 $t1(1)이 다르므로 분기하지 않음
    2. beq $t0, $t2, case_2 - $t0(2)와 $t2(2)가 같으므로 case_2로 분기
    3. case_2에서 “Case 2 selected” 출력
    4. j end_swtich종료 부분으로 점프
    5. 프로그램 종료

SLT/SLTI 예제 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# SLT/SLTI 명령어를 사용한 예제 코드

# 초기화
li $t0, 15       # 테스트할 값 15를 $t0에 로드 (이 값은 변경 가능)
li $t1, 10       # 하한값(10)을 $t1에 로드
li $t2, 20       # 상한값(20)을 $t2에 로드

# $t0 < 10 확인하기 (SLTI 사용)
slti $t3, $t0, 10      # $t0 < 10이면 $t3 = 1, 아니면 $t3 = 0
bne $t3, $zero, too_small  # $t3 != 0 (즉, $t0 < 10)이면 'too_small'로 점프

# $t0 >= 20 확인하기 (SLTI 사용)
slti $t3, $t0, 20      # $t0 < 20이면 $t3 = 1, 아니면 $t3 = 0
beq $t3, $zero, too_large  # $t3 == 0 (즉, $t0 >= 20)이면 'too_large'로 점프

# 숫자가 10과 20 사이에 있으면 (10 <= $t0 < 20) "Just Right" 출력
li $v0, 4              # 문자열 출력 시스템 콜
la $a0, just_right     # "Just Right" 문자열 주소 로드
syscall                # 시스템 콜 실행
j end                  # 'end' 레이블로 점프

too_small:
    # $t0 < 10일 경우 "Too Small" 출력
    li $v0, 4              # 문자열 출력 시스템 콜
    la $a0, too_small_str  # "Too Small" 문자열 주소 로드
    syscall                # 시스템 콜 실행
    j end                  # 'end' 레이블로 점프

too_large:
    # $t0 >= 20일 경우 "Too Large" 출력
    li $v0, 4              # 문자열 출력 시스템 콜
    la $a0, too_large_str  # "Too Large" 문자열 주소 로드
    syscall                # 시스템 콜 실행

end:
    # 프로그램 종료
    li $v0, 10             # 프로그램 종료 시스템 콜
    syscall                # 시스템 콜 실행

# 데이터 섹션
.data
too_small_str: .asciiz "Too Small\n"
too_large_str: .asciiz "Too Large\n"
just_right: .asciiz "Just Right\n"
  1. 테스트 값 $t0이 10보다 작은지 slti로 확인
  2. 10보다 작으면 “Too Small” 출력
  3. 10보다 크거나 같다면, 20보다 작은지 확인
  4. 20보다 크거나 같으면 “Too Large”를 출력
  5. 그 외의 경우 10 <= $t0 <= 20 이면 “Just Right” 출력

1부터 N까지의 짝수 합 계산 예제

# 1부터 N까지의 모든 짝수의 합 계산 프로그램

# 초기화
li $t0, 10      # N 값 설정 (예: 10)
li $t1, 1       # 카운터 초기화 ($t1 = 1)
li $t2, 0       # 합계 초기화 ($t2 = 0)

for_loop:
    # 카운터($t1)가 N($t0)보다 작거나 같은지 확인
    slt $t3, $t1, $t0    # $t1 < $t0 이면 $t3 = 1, 아니면 $t3 = 0
    beq $t3, $zero, end  # $t3 == 0 (즉, $t1 >= $t0)이면 반복문 종료

    # 현재 카운터 값($t1)이 짝수인지 확인 (비트 AND 연산 사용)
    andi $t3, $t1, 1     # $t1 & 1 (최하위 비트 확인)
    bne $t3, $zero, next # $t3 != 0 (즉, $t1이 홀수)이면 next로 점프

    # 현재 값이 짝수이면 합계에 더함
    add $t2, $t2, $t1    # $t2 = $t2 + $t1 (짝수 값을 합계에 추가)

next:
    # 카운터 증가
    addi $t1, $t1, 1     # $t1 = $t1 + 1
    j for_loop           # 반복문의 시작으로 다시 점프

end:
    # 최종 합계 출력
    li $v0, 1            # 정수 출력 시스템 콜
    move $a0, $t2        # 합계 값을 $a0에 복사
    syscall              # 시스템 콜 실행

    # 프로그램 종료
    li $v0, 10           # 프로그램 종료 시스템 콜
    syscall              # 시스템 콜 실행
  1. 반복문:
    • slt $t3, $t1, $t0으로 $t1 < $t0 검사하고, 결과가 0이면 반복문 종료
  2. 짝수 확인:
    • andi $t3, $t1, 1카운터의 최하위 bit 확인
    • AND 연산 결과가 0이면 짝수, 1이면 홀수
    • 결과가 1이면 next로 점프
  3. 짝수 처리:
    • 현재 값이 짝수면 $t2에 더함
  4. 카운터 증가 및 반복:
    • addi $t1, $t1, 1로 카운터 증가
    • j for_loop로 반복문으로 돌아감
  5. 결과 출력 및 종료(30 출력)
This post is licensed under CC BY 4.0 by the author.