전공/시스템 프로그래밍

[시스템 프로그래밍 6-3] 어셈블리어 JMP와 LOOP명령어

뜨거운 개발자 2023. 4. 6. 13:31

JMP and LOOP Instructions

  • cpu는 명령을 순차적으로 로드하고 처리를 하지만, 그에 반해 각각의 프로그램에 들어간 명령어들은 조건부로 동작할 수 있다.
    • CPU 상태 플래그(Status flag) 값에 따라 프로그램의 컨트롤 위치를 변경 할 수 있다.
  • 어셈블리 언어 프로그램은 조건부 명령어(conditional instructions)를 사용하여 IF 문 및 루프와 같은 high-level 상태를 구현합니다.
    • 각 conditional instruction은 컨트롤을 다른 메모리 주소로 이동(점프) 를 할 수가 있다.
    • 브랜치 또는 컨트롤 변경(transfer of control)은 명령의 실행 순서를 변경하는 방법이다.
  • 우리는 2가지 타입의 type of transfer방식을 제공한다.

1. Unconditional Transfer(무조건 이동)

  • 모든 경우(무조건)에 제어권이 새 위치로 이전됩니다. (goto문을 생각)
  • 새 주소가 명령 포인터(instruction pointer)(EIP)에 로드되어 새 주소에서 실행이 계속됩니다

2. Conditional Transfer

  • 특정 조건이 참이면 프로그램이 분기됩니다.
  • 다양한 조건부 전송 명령을 결합하여 조건부 논리 구조를 만들 수 있습니다.
  • CPU는 ECX 플래그 레지스터의 내용을 기반으로 참/거짓 조건을 해석합니다.

1. JMP Instruction

  • 이 명령은 어셈블러에 의해 offset으로 해석된 코드라벨이 식별된 대상에 대해 destination으로 Unconditional Transfer을 야기한다.
  • 사용법 JMP destination
    • 여기서 destination은 앞에서 즉 코드에서 미리 지정해둔 label이다. (사실 label은 offset에 불과하기 때문에)
  • 루프 만들기
    • JMP명령은 루프를 label로 이동을 이용해서 쉽게 만들 수 있다.
    top :
    			.
    			.
    			jmp top ;repeat the endless loop
    • 이 코드는 무한루프이다.

2. LOOP Instruction

  • ECX레시스터를 카운터로 사용한다.
  • 이 명령은 특정 횟수만큼 정해진 블록을 수행한다.
  • ECX는 자동으로 카운터로 사용되기 때문에 루프가 반복될 때마다 ECX 카운터가 1씩 감소한다.
  • 사용법:LOOP destination
  • 루프 대상은 현재 위치 카운터에서 -128에서 +127바이트 이내여야 한다.
  • 루프 실행과정
    1. ECX에서 1을 뺀다.
    1. 다음으로 ECX와 0을 비교한다.
      1. 0이 아닌경우 목적지로 식별되는 레이블로 점프한다.
      1. 만약 0인경우에 점프가 발생하지 않고 루프 다음 instruction 으로 제어권이 넘어간다.
		mov ax ,0
		mov ecx, 5
L1 :
		inc ax
		loop L1
  • 결과로 ecx레지스터는 0이 될 것이고 ax는 5가 될 것이다.

주의사항

  • ECX레지스터를 0으로 초기화하는 실수를 할 수있다.
    • 이 경우 LOOP 명령은 ECX를 FFFFFFFFh로 감소시키고 루프가 4,294,967,296회 반복됩니다!
    • 만약 16비트에서 프로그래밍 하는 경우(real mode)는 CX를 사용하는데 65536회 반복된다.
  • LOOP 명령의 허용된 점프 범위를 초과할 만큼 큰 루프를 만들면 에러가 발생한다.
  • 루프 내에서 ECX를 수정해야 하는 경우, 루프 시작 시 변수에 저장하고 LOOP 명령 직전에 복원할 수 있습니다. (중간에 ecx로 연산을 수행한 코드 예시이다.)
.data
count DWORD ?
.code
		mov ecx,100 ;set loop count
top :
		mov count,ecx ;save the count
		.
		mov ecx,20 ;modift ecx
		.
		mov ecx,count ;restore loop count
		loop top
  • 이런 경우는 빈번하게 발생하는데 그 이유는 레지스터의 갯수가 제한적이기 때문에 발생한다.

Nested Loops(중첩 루프)

  • 루프안에 다른 루프를 저장할 때 너는 바깥쪽의 ECX 레지스터의 숫자(카운터)를 고려해야만 한다.
  • 변수에 저장하는 방식을 사용한다.
.data
count DWORD ?
.code
		mov ecx,100   ;set outer loop count
L1 :
		mov count,ecx ;save outer loop count
		mov ecx,20    ;set inner loop count
L2 :
		.
		.
		loop L2       ;repeat the inner loop
		mov ecx,count ;restore outer loop count
		loop L1       ;repeat the outer loop
  • 일반적으로 이중루프 이상으로 코드가 생기는 경우 상당히 작성하기가 어려워진다.
  • 사용중인 알고리즘이 깊은 루프 중첩이 필요한 경우 내부 루프 중 일부를 서브루틴으로 이동시켜야 한다.

디버깅 사용

정수 배열 반복문 예제

문자열 복사 예제

  • 종료값이 널인 바이트 배열로 표현되는 문자열을 복사하는 루프를 사용하는 어셈블리 언어 프로그램이다.
  • MOV 명령은 두 개의 메모리 피연산자를 가질 수 없으므로 각 문자는 소스 문자열에서 AL로 이동한 다 음 AL에서 대상 문자열로 이동합니다

Uploaded by N2T

728x90