외로운 Nova의 작업실
Assembly 언어 공부 - 18(JMP와 LOOP 명령어 이론 및 실습) 본문
안녕하세요, 오늘은 JMP 와 LOOP 명령어가 무엇인지 배워보고 직접 실습해보는 시간을 가져보도록 하겠습니다.
JMP 명령어
JMP destination 은 코드레이블로 표시되는 목적지로 무조건 이동시킵니다. 간단한 JMP 명령어 코드를 봐보도록 하겠습니다.
top :
...
...
JMP top
JMP 명령어에의해 위 코드는 반복되게 됩니다. 또한 JMP는 무조건 적이여서 루프를 빠져나가는 다른 방법이 없으면 위와 같은 루프는 끝없이 계속될 것 입니다.
LOOP 명령어
LOOP destination 은 ECX가 자동적으로 카운트로 사용되며 루프를 반복할때마다 ECX의 값을 감소시킵니다. 또한, 루프의 목적지는 현재 위치 카운터에서 -128~+127 바이트 내에 있어야합니다.
LOOP 명령어의 실행은 두단계로 나뉩니다. 첫번째, ECX에서 1을 빼고 두번째, ECX가 0이 아니면 destination으로 점프합니다. 간단한 LOOP 명령어 코드를 봐보도록 하겠습니다.
mov ax, 0
mov ecx, 5
L1 :
inc ax
LOOP L1
위 코드에서 L1은 5번 반복하게되며, ax의 값은 결국 5가 되게됩니다. 처음에 ecx를 0으로 초기화해버리면 LOOP는 4,294,967,296번 반복하게됩니다. 따라서 ecx의 초기값이 굉장히 중요합니다.
또한, 중첩 루프의 경우 루프안에서 ECX의 값을 수정해야합니다. 수정할때는 꼭 ECX를 변수에 저장하고 새로운 값을 집어 넣어줘야합니다. 중첩 루프의 간단한 코드를 봐보도록 하겠습니다.
.data
count DWORD ?
.code
mov ecx, 100
L1 :
mov count, ecx
mov ecx, 20
L2 :
...
...
LOOP L2
mov ecx, count
LOOP L1
위 코드는 결국 L1은 100번, L2는 2000번 실행됩니다. 일반적으로 두레벨 이상으로 중첩된 루프는 작성하기가 어렵다보니중첩 루프를 서브 루틴으로 나누어 루프를 실행시키는 방법도 있습니다.
정수 배열 합하기
위 2가지 명령어를 가지고 흔히 쓰는 코드인 정수 배열의 값들을 모두 합하는 실습을 해보도록 하겠습니다. 바로 코드부터 보시죠.
include c:\assembly\irvine32.inc
includelib c:\assembly\irvine32.lib
includelib c:\assembly\kernel32.lib
includelib c:\assembly\user32.lib
PDWORD TYPEDEF PTR DWORD
.data
dArray DWORD 10000h, 20000h, 30000h, 40000h
ptrd PDWORD dArray
.code
main PROC
mov esi, ptrd ;간접 주소 접근을 위해 esi에 배열의 주소값 할당
mov ecx, LENGTHOF dArray ;ecx 카운터에 배열의 개수를 할당
mov eax, 0h ;eax는 합을 저장할것임으로 초기화
L1 :
add eax, [esi] ;eax에 배열의 값저장
add esi, TYPE dArray ;esi에 다음 배열의 주소 저장
LOOP L1 ;ecx값 하나 빼고 0이 아니면 L1 반복
call DumpRegs
exit
main ENDP
END main
위 코드를 실행시켜보면,
잘 실행 된 것을 확인 할 수 있습니다.
문자열 복사하기
정수 배열의 합 말고도 자주 코딩해야하는 문자열 복사하는 기능은 루프를 사용하여 간단하게 구현할 수 있습니다. 바로 코드부터 보시죠.
include c:\assembly\irvine32.inc
includelib c:\assembly\irvine32.lib
includelib c:\assembly\kernel32.lib
includelib c:\assembly\user32.lib
.data
source BYTE "hello world", 0
target BYTE LENGTHOF source DUP(0)
.code
main PROC
mov esi, 0 ;esi를 배열의 index로 사용하기위해 0으로 초기화
mov ecx, LENGTHOF source ;ecx에는 source 배열의 원소의 개수를 넣어줌
L1 :
mov al, source[esi] ;레지스터에 source 원소의 값을 넣어줌
mov target[esi], al ;target 원소에 레지스터 값을 넣어줌
inc esi ;index값을 1증가시킨다. byte이기때문에 1임
LOOP L1
mov eax, DWORD PTR target
call DumpRegs
exit
main ENDP
END main
위 코드를 실행하면,
아스키코드 표를 봐보자
eax에 l l e h가 저장되었을 것이다. 'h' = 68h, 'e' = 65h, 'l' = 6Ch 이므로 잘 target에 저장된 것을 확인 할 수 있다.
'Programming > Assembly' 카테고리의 다른 글
Assembly 언어 공부 - 20(라이브러리 예제 프로그램) (0) | 2022.08.23 |
---|---|
Assembly 언어 공부 - 19(라이브러리 프로시저 설명) (0) | 2022.08.18 |
Assembly 언어 공부 - 17(간접 주소 지정 이론 및 실습) (0) | 2022.08.01 |
Assembly 언어 공부 - 16(데이터 관련 연산자와 디렉티브 이론 및 실습) (0) | 2022.08.01 |
Assembly 언어 공부 - 15(산술 이론 및 실습) (0) | 2022.07.30 |