# 6. Control Structures

## 조건문 if, then, else

``````if (E) then
S1
else
S2
``````

이런 high level 프로그래밍 구조가 Assembly 에선 아래와 같은 구조가 됨.

``````if_eval:    /* Assembler that evaluates E and updates the cpsr accordingly */

bXX else    /* Here XX is the appropiate condition */
then_part:    /* assembler for S1, the "then" part */
b end_of_if
else:        /* assembler for S2, the "else" part */
end_of_if:
``````

## 반복문 Loops

``````while (E)
s
``````
``````while_condition:    /* assembler to evaluate E and update cpsr */
bXX end_of_loop    /* If E is false, then leave the loop right now */

/* assembler of S */
b while_condition    /* Unconditional branch to the beginning */
end_of_loop:
``````

## Asm code for 1+2+3+4+...+22

• 내가 짜본 코드: 틀렸음
``````  mov r1 #0
mov r0 #1
while_condition:
bvs end_of_loop    /* overflow condition for cpsr */
mov r1 r0    /* r1 1 */
add r0 r0 #1     /* r0 1+1 */
add r1 r1 r0    /* r1 1 + 2 */
b while_condition
end_of_loop:
``````

my code: 22까지 더하면 253인데 overflow 발생한다고 생각했음.

• loop01.s Reference code

``````  /* -- loop01.s */
.text
.global main
main:
mov r1, #0       /* r1 <- 0 (sum val) */
mov r2, #1       /* r2 <- 1 (counter val) */
loop:
cmp r2, #22      /* compare r2 and 22 */
bgt end          /* branch if r2 > 22 to end */
add r1, r1, r2   /* r1 <- r1 + r2 */
add r2, r2, #1   /* r2 <- r2 + 1 */
b loop
end:
mov r0, r1       /* r0 <- r1 */
bx lr
``````
``````      cmp r2, #22
bgt end
``````

cpsr will be updated by cmp operation, then branch out by "gt" flag

• 참고: loop02.s loop01 보다 개선된 버전이다.

``````  .text
.global main
main:
mov r1, #0       /* r1 ← 0 */
mov r2, #1       /* r2 ← 1 */
b check_loop     /* unconditionally jump at the end of the loop */
loop:
add r1, r1, r2   /* r1 ← r1 + r2 */
add r2, r2, #1   /* r2 ← r2 + 1 */
check_loop:
cmp r2, #22      /* compare r2 and 22 */
ble loop         /* branch if r2 <= 22 to the beginning of the loop */
end:
mov r0, r1       /* r0 ← r1 */
bx lr
``````

01과 명령어 갯수는 동일하다. 하지만 01과 다르게 마지막 조건에서 branching 하는 횟수가 하나 적다. ble loop 다음 end: 로 branching없이 진행되기 때문이다.

## Asm code for 3n + 1 problems

다른 말로 콜라츠 추측 이라고 부른다

임의의 자연수가 다음 조작을 거쳐 항상 1이 된다는 추측

``````1. 짝수라면 2로 나눈다.
2. 홀수라면 3을 곱하고 1을 더한다.
3. 1이면 조작을 멈추고, 1이 아니면 첫 번째 단계로 돌아간다.
예를 들어, 6 에서 시작한다면, 차례로 6, 3, 10, 5, 16, 8, 4, 2, 1 이 된다.
``````
``````n = ...;
while (n != 1)
{
if (n % 2 == 0)
n = n / 2;
else
n = 3*n + 1;
}
``````
``````/* -- collatz.s */
.text
.global main
main:
mov r1, #123           /* r1 <- 123 */
mov r2, #0             /* r2 <- 0 */
loop:
cmp r1, #1             /* compare r1 and 1 */
beq end                /* branch to end if r1 == 1 */

and r3, r1, #1         /* r3 <- r1 & 1 */
cmp r3, #0             /* compare r3 and 0 */
bne odd                /* branch to odd if r3 != 0 */
even:
mov r1, r1, ASR #1     /* r1 <- (r1 >> 1) */
b end_loop
odd:
add r1, r1, r1, LSL #1 /* r1 <- r1 + (r1 << 1) */
add r1, r1, #1         /* r1 <- r1 + 1 */

end_loop:
add r2, r2, #1         /* r2 <- r2 + 1 */
b loop                 /* branch to loop */

end:
mov r0, r2
bx lr
``````
``````    and r3, r1, #1         /* r3 <- r1 & 1 */
``````

bitwise operator (AND)

``````    mov r1, r1, ASR #1     /* r1 <- (r1 >> 1) */
``````

ASR (arithmetic shift right) 로 추가 reg사용없이 쉬프트 가능 for r1 <- r1/2

``````    add r1, r1, r1, LSL #1
``````

LSL (logical shift left) r1 x 2 한 뒤 다시 r1을 더해서 r1 x 3이 됨.