본문 바로가기

Assembly

4-4강 - Data Transfer, Addressing and Arithmetic 4 (Indirect Addressing, JMP & LOOP)

4. Indirect Addressing

1) Indirect Operands

1> pointer처럼 변수의 주소를 이용해서 접근이 가능하다. 

- OFFSET을 이용해서 주소를 찾고

- []를 이용해서 저장된 값을 MOV에 의해 레지스터로 전달된다.

 

2> 예시 1

(OFFSET val1이 8000이라면)

10h 20h 30h
8000 8001 8002
val1 val1+1 val1+2
.data
val1 BYTE 10h, 20h, 30h

.code
    mov esi, OFFSET val1
    mov al, [esi]         ; AL = 10h
    inc esi
    mov al, [esi]         ; AL = 20h
    inc esi
    mov al, [esi]         ; AL = 30h

- line 1 

  • OFFSET을 이용해서 val1의 맨 앞 주소를 파악한다.
  • 확실히 esi는 val1의 첫 번째 원소인 BYTE 자료형의 10h를 가리키고 있다.

 

3> 예시 2

esi가 가리키는 곳이 어떤 자료형인지 모르는 경우 PTR을 사용해야 한다.

.data
myCount WORD 0

.code
    mov esi, OFFSET myCount
    inc [esi]          		; error: ambiguous
    int WORD PTR [esi] 		; ok
10 20 30 00 00
8000 80001 8002 8003 8004
val1 val1+1 val1+2 val1+3 val+4

- 이 경우 val1+3에서 inc연산을 가하면 WORD 단위로 증가할 지 BYTE 단위로 증가할 지 애매해진다.

 

 

4> Array Sum Example

.data
arrayW WORD 1000h, 2000h, 3000h

.code
    mov esi, OFFSET arrayW
    mov ax, [esi]
    add esi, 2      		; or: add esi, TYPE arrayW
    add ax, [esi]
    add esi, 2
    add ax, [esi]   		; AX = sum of the array

 

2) Indexed Operands

1> register에 상수를 더해서 effective address를 만들 수 있다.

2> 'label + reg' 와 'label[reg]'는 같은 의미이다.

3> 예시

.data
arrayW WORD 1000h,2000h,3000h

.code
mov esi,0
mov ax, [arrayW + esi] 	; AX = 1000h
mov ax, arrayW[esi] 	; alternate format
add esi, 2
add ax, [arrayW + esi]

 

3) Pointers

1> 다른 변수의 OFFSET을 저장하는 포인터 변수를 선언할 수 있다.

2> 예시

.data
arrayW WORD 1000h, 2000h, 3000h
ptrW  DWROD arrayW				; alternative format : ptrW DWORD OFFSET arrayW

.code
    mov esi, ptrW
    mov ax, [esi]  				; AX = 1000h

 

5. JMP and LOOP Instructions

1) JMP (Instruction)

1> 설정한 target으로 점프

2> 사용

JMP target : target으로 jump한다.

3> 예시

top:
    .
    .
    jmp top

4> 현재 procedure 밖의 label로 점프하려면 global label이라는 특별한 type이 필요합니다.

 

cf> EIP : Instruction Pointer

CPU가 가야할 주소

 

2) LOOP (Instruction)

1> 반복

- 반복문은 target까지 이동했다가 반복문의 어떤 조건을 만족하지 못하면 다시 원래의 자리로 돌아오는 구조이다.

- realtive offset : target~현재 위치 사이의 거리를 byte 수로 나타낸 것

- realtive offset은 EIP에 더해진다.

- backward로 돌아갈 때 = EIP 감소 / forward로 나아갈 때 = EIP 증가

2> 사용

LOOP target : [1] ECX를 1을 먼저 감소시키고 [2] 특정 조건(ECX가 0이 아니면)이면 target으로 점프한다. 

- target으로 돌아가는 것이 곧 loop를 반복하는 것이다.

- ECX가 0이 되면 loop를 멈출 수 있다. (다만 맨 처음에 ECX를 감소시키니 ECX가 처음에 0인 경우 ECX 한바퀴를 돈다.)

 

3> 예시 1

mov ax,0
mov ecx,5
L1: add ax,cx
loop L1			; ECX가 0이 될 때까지 L1 반복 (L1을 할 때마다 ECX는 1씩 감소한다.)

- loop L1 :

  • ECX가 0이 될 때까지 L1 반복
  • L1을 할 때마다 ECX는 1씩 감소한다.
  • 처음에는 5(cx)를 ax에 더하고, 4(cx)를 ax에 더하고 ... 1(cx)을 ax에 더하고 그 다음에는 cx가 0이므로 loop을 멈춘다.

 

4> 예시 2

relative offset이 SBYTE인 경우 => 0의 뒤로는 -128까지 있고, 앞으로는 127까지 있다.

    mov ax, 6
    mov ecx, 4
L1:
    inc ax
    loop L1		

- L1은 4번 시행되고 

- AX=10이 된다.

 

5> 예시 3

    mov ecx, 0
X2:
    inc ax
    loop X2

- (맨 처음) loop X2 : [1] ECX 1 감소 -> [2] ECX가 0인지 확인 (0이 아니다.)

- ECX는 32bit이므로 1바퀴 돌려면 4,294,967,296회 loop를 실행해야 한다.

 

6> 예시 4 : Nested Loop

.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

 

7> 예시 5 : Summing an Integer Array

.data
intarray WORD 100h,200h,300h,400h

.code
	mov edi,OFFSET intarray 	; address of intarray
	mov ecx,LENGTHOF intarray 	; loop counter
	mov ax,0 			; zero the accumulator
L1:
	add ax,[edi] 			; add an integer
	add edi,TYPE intarray 		; point to next integer
	loop L1 			; repeat until ECX = 0

 

8> 예시 6 : Copying a String

.data
source BYTE "This is the source string",0
target BYTE SIZEOF source DUP(0)

.code
	mov esi,0 			; index register
	mov ecx,SIZEOF source 		; loop counter
L1:
	mov al,source[esi] 		; get char from source
	mov target[esi],al 		; store it in the target
	inc esi 			; move to next character
	loop L1 			; repeat for entire string