[ASM] 반복문
👻 반복문
특정 조건을 만족하는 동안 반복적으로 실행되는 코드를 의미한다. 어셈블리에서는 loop
명령어를 사용한다. 무한 루프에 빠지지 않으려면 제어식을 필수로 지정해줘야 한다. 이전에 배웠던 add
나 sub
를 사용해도 되지만 증감 연산자를 사용해 주는 것이 메모리 절약적인 측면에서 더 좋다.
증감 연산자
- dec : sub와 동일
- dec ecx 👉 sub ecx, 1
- inc : add와 동일
- inc ecx 👉 add ecx, 1
🌱 loop
Hello World를 10번 출력해야 한다면?
일단 loop
없이 점프 시리즈로만 만들면 이렇게 된다.
mov al, 10
LABEL_LOOP:
PRINT_STRING msg
NEWLINE
dec al
cmp al, 0
jne LABEL_LOOP
xor rax, rax
ret
section .data
msg db 'Hello World', 0x00
이전 시간에 배웠던 라벨을 이용해서 범위를 지정해주고 인덱스를 비교하면서 0이 될때까지 점프하여 반복하는 것이다.
loop
라는 명령어를 사용하면 ecx
에 반복 횟수를 넣어 자동으로 1씩 감소시키며 알아서 반복이 되다 빠져나오게된다. 단, PRINT_STRING
이나 PRINT_DEC
같은 매크로를 루프 내부에 사용하게 되면 short jump is out of range
라는 에러가 나게되는데, 이는 loop가 점프할 수 있는 길이가 정해져있다는 뜻이고 해당 매크로가 의도치않게 점프할 주소값을 멀리 이동시켜버려 이러한 결과가 나오게 되는 것이다.
그래서 위의 예제로는 loop문을 만들 수는 없고, 다른 예제를 통해 loop문을 만들어보기로 하자.
1에서 100까지의 합을 구해서 출력하라.
이번에는 loop
를 사용하여 구현해보자.
mov ecx, 100
xor ebx, ebx ; 0으로 초기화
LABEL_LOOP_SUM:
add ebx, ecx
loop LABEL_LOOP_SUM
PRINT_DEC 4, ebx
NEWLINE
결과값은 5050으로 나온다는 것을 알 수 있다.
위의 예제는 loop 없이 구현 가능하다.
mov eax, 100 ; 최종 목적지 xor ebx, ebx ; mov ebx, 0 / ebx : 결과물 xor ecx, ecx LABEL_SUM: inc ecx ; add ecx, 1과 동일 add ebx, ecx cmp ecx, eax jne LABEL_SUM PRINT_DEC 4, ebx NEWLINE
👻 글을 마치며
이번 시간에는 어셈블리어로 반복문을 나타내는 방법에 대해 알아보았다. loop라는 명령어도 있지만 점프를 하는 데에 범위 제한이 있어 print와 관련된 매크로들을 사용할 수 없어서 아쉬웠다. 그래도 loop를 쓰지 않고도 사용하는 방식이 크게 불편하지 않아서 반복문의 내용에 따라 알맞게 사용하는 게 좋을 것 같다.
Leave a comment