Lecture #7 어셈블리어 (4) - 8086 매크로 어셈블리어 시스템프로그래밍
INCLUDE 의사 명령(1) 예제 프로그램 #1 AL 레지스터의 값을 ASCII 코드 16진수 값으로 화면에 출력하는 프로그램 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; ;--------------------------------------------------------- PUTAL: MOV BL, 10H MUL BL MOV LEVEL1, AH MOV AH, 0 MOV BL, 10H DIV BL MOV LEVEL2, AL MOV DL, LEVEL1 CALL PUTHEX MOV DL, LEVEL2 RET PUTHEX: CMP DL, 0AH JAE HEX2 ADD DL, ‘0’ JMP HEX3 HEX2: ADD DL, ‘A’-0AH HEX3: MOV AH, 2 INT 21H RET ;--------------------------------------------------------- LEVEL1 DB ? LEVEL2 DB ? ; START: MOV AX, MAIN MOV DS, AX MOV AL, 3FH CALL PUTAL MOV AH, 4CH MAIN ENDS END START 시스템프로그래밍
INCLUDE 의사 명령(2) 예제 프로그램 #1 설명 PUTAL 프로시저 – AL 레지스터의 값을 2자리의 ASCII 16진수로 출력하는 서브루틴 PUTHEX 프로시저 – DL 레지스터의 값에 해당하는 문자 (‘0’~’9, ‘A’~’F’)로 바꾸어 출력하는 서브루틴 END 명령에서 프로그램 시작 위치(START)를 지정 시스템프로그래밍
INCLUDE 의사 명령(3) 모듈별 분할 프로그래밍 (1) PUTAL 프로시저를 별도의 모듈(어셈블리 파일)로 작성한다 파일이름 – PUTAL.SUB ; MODULE – PUTAL.SUB ; PUTAL: MOV BL, 10H MUL BL MOV LEVEL1, AH MOV AH, 0 MOV BL, 10H DIV BL MOV LEVEL2, AL MOV DL, LEVEL1 CALL PUTHEX MOV DL, LEVEL2 RET ;--------------------------------------------------------- PUTHEX: CMP DL, 0AH JAE HEX2 ADD DL, ‘0’ JMP HEX3 HEX2: ADD DL, ‘A’-0AH HEX3: MOV AH, 2 INT 21H RET ;--------------------------------------------------------- LEVEL1 DB ? LEVEL2 DB ? 시스템프로그래밍
어셈블 과정에서 MASM 어셈블러에 의해 소스 확장이 이루어진 다음에 어셈블이 수행된다. INCLUDE 의사 명령(4) 모듈별 분할 프로그래밍 (2) 모듈 PUTAL.SUB을 이용할 경우 INCLUDE 의사 명령을 이용하여 예제 프로그램 #1을 다음과 같이 수정할 수 있다 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; INCLUDE PUTAL.SUB START: MOV AX, MAIN MOV DS, AX MOV AL, 3FH CALL PUTAL MOV AH, 4CH INT 21H MAIN ENDS END START 어셈블 과정에서 MASM 어셈블러에 의해 소스 확장이 이루어진 다음에 어셈블이 수행된다. 시스템프로그래밍
INCLUDE 의사 명령(5) 모듈별 분할 프로그래밍 (3) 장점 단점 프로그램을 기능별로 분할함으로써 이해가 용이 공동 및 병행 개발이 가능하여 효율적 한번 작성된 루틴을 효과적으로 반복 사용이 가능 단점 INCLUDE 의사 명령에 대한 소스 확장 과정이 필요 어셈블을 위한 전처리가 필요 시스템프로그래밍
레지스터 보존(1) 레지스터 보존 프로시저 호출을 사용하는 경우에 프로시저에서 호출 루틴에서 사용하는 레지스터 값을 변경하는 경우 프로시저에서 복귀하여 원래 루틴이 실행될 때에 오동작이 발생한다. 레지스터 보존(Register Housekeeping) 호출 루틴에서 프로시저가 사용하는 레지스터의 값을 보관한 다음, 프로시저 복귀 후에 레지스터 값을 원래대로 복구한다. 별도의 메모리를 이용한 레지스터 보존 스택을 이용한 레지스터 보존 시스템프로그래밍
PUTAL 프로시저에서 BX 레지스터를 사용하기 때문에 원래 값을 별도의 메모리에 저장해둔다 레지스터 보존(2) 예제 프로그램 #2 변수 NUM에 저장되어 있는 값들을 16진수로 출력하는 프로그램 PUTAL 프로시저에서 BX 레지스터를 사용하기 때문에 원래 값을 별도의 메모리에 저장해둔다 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; INCLUDE PUTAL.SUB START: MOV AX, MAIN MOV DS, AX MOV BX, OFFSET NUM MOV SI, 0 NEXT: MOV AL, [BX+SI] CMP AL, 0 JE EXIT MOV BXSAVE, BX CALL PUTAL MOV BX, BXSAVE INC SI JMP NEXT EXIT: MOV AH, 4CH INT 21H ; BXSAVE DW ? NUM DB 01H, 23H, 45H, 67H, 89H DB 0ABH, 0CDH, 0EFH, 00H MAIN ENDS END START 시스템프로그래밍
레지스터 보존(3) 예제 프로그램 #2 문제점 레지스터 보존을 위해 별도의 메모리 공간을 사용 레지스터 값을 메모리에 전송하고 레지스터 값을 복구하기 위해 다시 읽어오는 과정이 요구됨으로 실행시간이 늘어난다. 시스템프로그래밍
PUSH & POP 명령(1) 스택(Stack) LIFO(Last-In First-Out) 동작을 지원하는 메모리 공간 8086 CPU는 스택 세그먼트를 지원한다 레지스터 SS(Stack Segment), SP(Stack Pointer)에 의해 관리 PUSH / POP 명령에 의해 스택 메모리에 데이터 전송 프로그램 + 데이터 스택 메모리 프로그램 메모리 할당 시스템프로그래밍
PUSH & POP 명령(2) PUSH & POP 명령 PUSH/POP 세그먼트 레지스터 16 비트 메모리 PUSH 명령은 operand의 16 비트 데이터를 스택(SS:SP)에 저장한다 POP 명령은 스택(SS:SP)에서 16 비트 데이터를 읽어와 operand에 저장한다 SP 레지스터 값은 PUSH/POP 명령에 의해 자동적으로 2씩 증감한다 16 비트 범용 레지스터 PUSH/POP 세그먼트 레지스터 16 비트 메모리 시스템프로그래밍
PUSH & POP 명령(3) PUSH & POP 명령 PUSH AX POP AX PUSH SP POP 시스템프로그래밍 F002 F003 F004 F005 F006 F007 F008 F009 이전의 SP 새로운 SP PUSH AX 번지 FFF0 FFF1 FFF2 FFF3 FFF4 FFF5 FFF6 FFF7 FFF8 FFF9 FFFA SP PUSH POP F002 F003 F004 F005 F006 F007 F008 F009 새로운 SP 이전의 SP POP AX 시스템프로그래밍
PUTAL 프로시저에서 BX 레지스터를 사용한다는 사실을 알아야 레지스터를 보존할 수 있다. PUSH & POP 명령(4) 스택을 이용한 레지스터 보존 (1) 예제프로그램 #2을 스택을 사용하여 수정 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN, SS:MAIN ; INCLUDE PUTAL.SUB START: MOV AX, MAIN MOV DS, AX MOV SS, AX MOV BX, OFFSET NUM MOV SI, 0 NEXT: MOV AL, [BX+SI] CMP AL, 0 JE EXIT PUSH BX CALL PUTAL POP BX INC SI JMP NEXT PUTAL 프로시저에서 BX 레지스터를 사용한다는 사실을 알아야 레지스터를 보존할 수 있다. EXIT: MOV AH, 4CH INT 21H ; NUM DB 01H, 23H, 45H, 67H, 89H DB 0ABH, 0CDH, 0EFH, 00H MAIN ENDS END START 시스템프로그래밍
PUSH & POP 명령(5) 스택을 이용한 레지스터 보존 (2) PUTAL 프로시저에서의 레지스터 보존 MOV DL, AL ; MODULE – PUTAL.SUB ; PUTAL: PUSH AX PUSH BX PUSH DX MOV BL, 10H MUL BL MOV DL, AH CALL PUTHEX MOV AH, 0 DIV BL MOV DL, AL POP DX POP BX POP AX RET ;--------------------------------------------------------- PUTHEX: PUSH AX PUSH DX CMP DL, 0AH JAE HEX2 ADD DL, ‘0’ JMP HEX3 HEX2: ADD DL, ‘A’-0AH HEX3: MOV AH, 2 INT 21H POP DX POP AX RET ;--------------------------------------------------------- 시스템프로그래밍
PUSH & POP 명령(6) 스택을 이용한 레지스터 보존 (3) 시스템프로그래밍 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN, SS:MAIN ; INCLUDE PUTAL.SUB START: MOV AX, MAIN MOV DS, AX MOV SS, AX MOV BX, OFFSET NUM MOV SI, 0 NEXT: MOV AL, [BX+SI] CMP AL, 0 JE EXIT ; PUSH BX CALL PUTAL ; POP BX INC SI JMP NEXT EXIT: MOV AH, 4CH INT 21H ; NUM DB 01H, 23H, 45H, 67H, 89H DB 0ABH, 0CDH, 0EFH, 00H MAIN ENDS END START 시스템프로그래밍
PUSH & POP 명령(7) 스택을 이용한 레지스터 보존 (4) 프로시저를 구현할 때에 프로시저 내에서 사용하는 레지스터는 스택에 보존하도록 한다 프로시저 시작 부분에서 레지스터를 스택에 PUSH 프로시저에서 반환하기 전에 레지스터 값을 스택에서 POP 호출 루틴에서 레지스터 보존에 대한 부담 없이 프로시저를 호출할 수 있도록 지원 시스템프로그래밍
논리 연산 명령(1) 비트 연산 명령 논리 연산 명령 비트 단위 연산을 수행하는 명령 논리 연산 명령 / 시프트 연산 명령 비트 단위로 논리 연산(and, or, not 등)을 수행하는 명령 AND / OR / NOT / XOR / TEST / NEG 시스템프로그래밍
논리 연산 명령(2) AND 명령 OR 명령 주로 비트 마스크(mask) 연산에 사용 예) AL 레지스터의 하위 4비트 값만 구하기 AND AL, 0FH OR 명령 주로 임의의 비트를 1로 세트하는 연산에 사용 예) AL 레지스터 최상위 비트를 1로 설정하기 OR AL, 80H 시스템프로그래밍
논리 연산 명령(3) XOR 명령 TEST 명령 주로 임의의 비트를 반전시키는 연산에 사용 예) AL 레지스터의 상위 4비트을 반전하기 XOR AL, 0F0H TEST 명령 AND 명령과 유사하나 operand 값을 변경하지 않고 연산 결과에 대해 플래그 레지스터의 상태 비트를 설정한다 주로 임의의 비트가 1인지를 검사하는 연산에 사용 예) AL 레지스터 최상위 비트를 1인지를 검사하기 TEST AL, 80H 시스템프로그래밍
논리 연산 명령(4) NEG 명령 부호있는 데이터에 대한 부호 반전(양수 음수) 예) AL 레지스터의 2의 보수 구하기 2의 보수 연산 NOT 명령을 실행한 후에 1을 더하여 결과를 없음 예) AL 레지스터의 2의 보수 구하기 NEG AL 시스템프로그래밍
논리 연산 명령(5) 예제프로그램 AL 레지스터에 대해 여러 가지 논리 연산을 수행한 후에 2진수 형태로 출력하는 프로그램 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; PUTBIN PROC NEAR TEST AL, 10000000B CALL BINOUT TEST AL, 01000000B TEST AL, 00100000B TEST AL, 00010000B TEST AL, 00001000B TEST AL, 00000100B TEST AL, 00000010B TEST AL, 00000001B RET PUTBIN ENDP BINOUT PROC PUSH AX PUSH DX JZ PUT0 MOV DL, ‘1’ JMP PUT1 PUT0: MOV DL, ‘0’ MOV AH, 2 INT 21H POP DX POP AX RET BINOUT EMDP ; CRLF PROC MOV DL, 0DH 시스템프로그래밍
논리 연산 명령(6) 예제프로그램 (계속) 시스템프로그래밍 MOV DL, 0AH MOV AH, 2 INT 21H POP DX POP AX RET CRLF ENDP ; START: MOV AX, MAIN MOV DS, AX XOR AX, AX CALL PUTBIN CALL CRLF MOV AL, 10101111B AND AL, 11110000B OR AL, 00000011B XOR AL, 11110000B CALL PUTBIN CALL CRLF NOT AL ; MOV AH, 4CH INT 21H MAIN ENDS END START 시스템프로그래밍
시프트 & 로테이트 명령(1) 시프트 & 로테이트 명령 비트 단위의 자리 옮김 명령 시프트 & 로테이트 명령에 의해 넘치는 비트는 CF(Carry Flag)로 전송된다 SHL SHR SAL SAR 범용 레지스터(8/16 비트) 1 ROL 메모리(8/16비트) , CL ROR RCL RCR 시스템프로그래밍
시프트 & 로테이트 명령(2) 시프트 명령 SHL(SHift logical Left) / SHR(SHift logical Right) SAL(Shift Arithmetic Left) / SAR(Shift Arithmetic Right) CF MSB LSB CF MSB LSB CF MSB LSB CF MSB LSB 시스템프로그래밍
시프트 & 로테이트 명령(3) 로테이트 명령 ROL(ROtate Left) / ROR(ROtate Right) RCL(Rotate through Carry Left) / RCR(Rotate through Carry Right) CF MSB LSB CF MSB LSB CF MSB LSB CF MSB LSB 시스템프로그래밍
시프트 & 로테이트 명령(4) 시프트 & 로테이트 명령 응용 곱셈 및 나눗셈에서 응용 2의 지수승 곱셈 Shift Left 2의 지수승 나눗셈 Shift Right 예) AL 레지스터에 16 곱하기 MOV CL, 4 SAL AL, CL AL 레지스터를 8로 나누기 MOV CL, 3 SAR AL, CL 실제 MUL/DIV 명령보다 빠른 속도로 연산을 수행 시스템프로그래밍
시프트 & 로테이트 명령(5) 예제프로그램 PUTAL 프로시저를 시프트 명령을 이용하여 수정 시스템프로그래밍 ; MODULE – PUTAL.SUB ; PUTAL: PUSH AX PUSH BX PUSH CX PUSH DX PUSH AX AND AL, 0F0H MOV CL, 4 SHR AL, CL CALL PUTHEX POP AX AND AL, 0FH POP DX POP CX POP BX RET ;--------------------------------------------------------- PUTHEX: PUSH AX PUSH DX CMP DL, 0AH JAE HEX2 ADD DL, ‘0’ JMP HEX3 HEX2: ADD DL, ‘A’-0AH HEX3: MOV AH, 2 INT 21H POP DX POP AX RET ;--------------------------------------------------------- 시스템프로그래밍