C H A P T E R

Chapter 2: 수의 체계

Chapter 2: 수의 체계

9
ㅔ

일반 명령문

공부할 내용

★ 기본적인 어셈블러 명령문

(1) MOVE, XCHG	: 정보의 복사, 교환 명령

(2) LEA : 오프셋을 얻는 명령

(3) LDS, LES : 완전한 주소를 얻는 명령

(4) PUSH, POP : 스택관련 명령

(5) PUSHA, POPA : 레지스터 값을 저장하는 명령

(6) PUSHF, POPF : 플래그스 레지스터의 값을 저장하는 명령

(7) NOP : 일을 하지 않는 명령

정보를 복사하는 명령: MOV

★ MOV : 자료를 한 곳에서 다른 곳으로 복사한다.

(형식)	MOV	destination, source

★ 데스티네이션 : 레지스터 또는 메모리의 한 공간(자료 항목)

소스 : 레지스터, 메모리의 한 공간 또는 즉치(immediate value)

MOV     AX, 0

MOV     BP, 200H

MOV     TOTAL, 2*1024

MOV     BX, SI

MOV     ES, AX

MOV     SEGADDR, DS

MOV     AX, TOTAL

MOV     BH, LIST[SI]

MOV 명령 사용의 제약 조건

(1) 소스의 길이와 데스티네이션의 길이는 같아야 한다.

MOV     BL, DX	(×)

MOV     SEGADDR, DS

MOV     BH, LIST[SI]

(2) IP 레지스터는 소스, 데스티네이션으로 사용해서는 안됨

(3) CS 레지스터는 데스티네이션으로 사용해서는 안됨

MOV     CS, 8970H	(×)

MOV     AX, IP	(×)

(4) 즉치를 세그먼트 레지스터에 복사할 수 없고, 한 세그먼트 레지스터의 값을 다른 세그먼트 레지스터에 직접 복사할 수 없다.

MOV     SS, 1000H	(×)

MOV     ES, DS	(×)

(5) 세그먼트 주소를 직접 세그먼트 레지스터에 복사해서는 안 된다.

MOV     DS, DSEG	(×)

MOV     AX, DSEG

MOV     DS, AX

(6) (메모리의) 한 자료 항목을 다른 자료 항목에 직접 복사할 수 없다.

MOV     ITEM1, ITEM2	(×)

(해결책)

1. 복사할 자료 항목이 작으면 레지스터를 중간 장소로 사용

MOV     AX, ITEM1

MOV     ITEM2, AX

2.  MOVSB와 MOVSW 명령을 사용 (15장)

정보를 교환하는 명령: XCHG

★ 두 레지스터 사이 또는 한 레지스터와 한 자료 항목 사이에서 정보를 서로 교환하는 명령

XCHG    AX, BX

XCHG    AX, SUM

XCHG    BLIST[SI], DL

XCHG    CH, CL

★ 제약 조건

(1) 두 오퍼랜드의 길이가 같아야 한다.

XCHG    AX, BL	(×)

XCHG    WLIST[SI], DL

(2) 세그먼트 레지스터의 내용을 교환해서는 안 된다는 것이다.

XCHG    AX, ES	(×)

(3) 두 자료 항목의 내용은 서로 교환할 수 없다.

XCHG    ITEM1, ITEM2	(×)

(다른 방법)

MOV     AX, ITEM1

XCHG    AX, ITEM2

MOV     ITEM1, AX

오프셋을 얻는 명령: LEA

★ 오프셋을 얻으려면 :

(1) OFFSET 연산자를 사용

예)	MOV	AX, OFFSET TOTAL

제약점 :	자료 항목이 반드시 이름으로 되어 있어야 한다. 즉, TOTAL[BX]와 같이 인덱스 된 주소일 수 없다.

(2) LEA : 두 번째 오퍼랜드의 오프셋을 얻어서 첫째 오퍼랜드에 자동적으로 복사하여 준다.

예)	LEA	AX, TABLE[BX]

완전한 주소를 얻는 명령: LDS와 LES

★ LDS : 데이터 세그먼트 레지스터를 로드(load data seg. register)

형식) LDS  레지스터, 더블워드주소

더블워드에는 세그먼트 주소와 오프셋이 저장되어 있음

DS ← 세그먼트 주소,  레지스터 ← 오프셋

예)	TABLE	DB      100 DUP(?)

T_ADDR	DD  ← 세그먼트, 오프셋 값이 들어있다고 가정.

..............

LDS	DX, T_ADDR

∃

LEA     DX, TABLE

MOV	DS, SEG TABLE

예) DATA1	SEGMENT

BUFFER  DB  'Hey...','$'

ADDR1   DD   ?

DATA1   ENDS

..........

CODE    SEGMENT  'CODE'

..........

MOV     AX, DATA1

MOV     WORD PTR ADDR1+2, AX

MOV     AX, OFFSET BUFFER1

MOV     WORD PTR ADDR1, AX

.........

LDS      DX, ADDR1

MOV     AH, 09h

INT      21h

스택에 복사하고 스택으로부터 복사하는 명령:

PUSH와 POP

★ POP과 PUSH 명령의 오퍼랜드는 16비트

PUSH	AX

PUSH	TABLE[BX]+24

PUSH	TYPE LIST

PUSH	1024

PUSH    0

POP	DS

POP	VALUE

★ PUSH와 POP은 두 가지 중요한 용도로 사용된다.

(1) 프로시저를 호출할 때 스택에 정보를 푸쉬함으로써 호출된 프로시저와 정보를 주고받는다.

예) PUSH    TOTAL

PUSH    SUBTOTAL

PUSH    TAX

PUSH    DISCOUNT

PUSH    ITEM

CALL    CALCULATE

(2) 스택을 임시 저장 영역으로 사용한다.

예) 다음은 ITEM1의 내용을 ITEM2로 옮기는 명령들이다.

; copy the contents of ITEM1 to ITEM2

LEA     SI, ITEM1

LEA     DI, ITEM2

MOV    CX, LENGTH ITEM1

CLD

REP  MOVSB

★ 이 명령들을 실행하고 나면 SI, DI, CX의 값이 변화되어 있다. 이 레지스터들에 잃어서는 안 되는 중요한 정보가 저장되어 있는 것이라면 어떻게 해야 하는가?

∀ SI, DI, CX에 있는 값을 스택에 미리 푸쉬하여 둠

; save the contents of SI, DX, CX

PUSH    SI

PUSH    DI

PUSH    CX

; copy the contents of ITEM1 to ITEM2

LEA     SI, ITEM1

LEA     DI, ITEM2

MOV     CX, LENGTH ITEM1

CLD

REP     MOVSB

; restore the contents of SI, DI, CX

POP     CX

POP     DI

POP     SI

레지스터 값을 저장하는 명령: PUSHA와 POPA

★ 여러 개의 레지스터 값을 저장할 때 유용함

PUSHA가 저장하는 레지스터의 값:

AX, CX, DX, BX, SP, BP, SI, DI

예)

; copy the contents of ITEM1 to ITEM2

PUSHA

LEA	SI, ITEM1

LEA	DI, ITEM2

MOV    CX, LENGTH ITEM1

CLD

REP    MOVSB

POPA

예) AX 레지스터에 값을 넣어 호출한 프로시저로 전달하려면, 모든 레지스터의 값을 복원한 후에 그 값을 AX에 복사하여 넣는다.

; set registers and return to calling program

POPA

MOV     AX, VALUE

RET

틀린 예

MOV     AX, VALUE

POPA

RET

★ PUSHA은 SP의 원래 값을 푸쉬하고 POPA은 SP를 복원하지 않는다.

플래그 레지스터의 값을 저장하는 명령:

PUSHF와 POPF

★ 플래그 레지스터(flags register)는 특별한 레지스터로써 16비트가 모두 독립적인 요소(individual entity)로 취급된다. 따라서, 플래그 레지스터의 값을 때로는 저장하고 복원할 수 있어야 한다.

★ PUSHF - push flags,  POPF - pop flags

예) 아래의 명령으로 AX의 값을 BX 의 값에 더할 수 있다.

ADD     BX, AX

그러나 ADD 명령은 플래그 레지스터의 비트를 여러 개 바꾸어    놓는다. 이 비트들이 바뀌지 않기를 바란다면, 아래와 같이 한다.

PUSHF

ADD     BX, AX

POPF

<참고> 플래그 레지스터의 구조 (다음 장에 나옴)

	15	14	13	12	11	10	9	8	7	6	5	4	3	2	1	0
					OF	DF	IF	TF	SF	ZF		AF		PF		CF

OF(Overflow Flag)

DF(Direction Flag) : 문자열 연산에서 인덱스 레지스터의 증가 방향

IF(Interrupt Flag) : 인터럽트 제어

TF(Trap Flag) : 특정 프로시저 수행 셋팅

SF(Sign Flag)

ZF(Zero Flag)

AF(Auxiliary Carry Flag) : BCD 연산에서의 Carry Flag

PF(Parity Flag)

CF(Carry Flag) : 덧셈, 뺄셈에서의 자리올림(carry) 또는 자리빌림(borrow)

아무 일도 하지 않는 명령: NOP

★ NOP : no operation

- 디버깅을 할 때 유용하게 쓰일 수 있다.

(특정 명령이 정말 필요했는지 알고자 할 때, 이를  NOP로 바꾸어

테스트하여 본다.)