230 likes | 435 Views
Lecture #6. 어셈블리어 (3) - 8086 매크로 어셈블리어. 프로그램 제어 명령. 조건분기 명령 CMP, JE, JZ, JNZ… 무조건분기 명령 JMP 루프 명령 LOOP 프로시저 정의 및 호출 매크로 정의 및 호출. 조건 분기 명령 (1). 조건 분기 명령 주어진 조건의 만족 여부에 따라 지정된 레이블의 주소로 분기 ‘비교 명령’ & ‘ 조건 분기 명령’이 결합하여 구성 C 언어의 IF 문장과 유사 e.g) if (i <= 100) {…}
E N D
Lecture #6 어셈블리어 (3)- 8086 매크로 어셈블리어 시스템프로그래밍
프로그램 제어 명령 • 조건분기 명령 • CMP, JE, JZ, JNZ… • 무조건분기 명령 • JMP • 루프 명령 • LOOP • 프로시저 정의 및 호출 • 매크로 정의 및 호출 시스템프로그래밍
조건 분기 명령 (1) • 조건 분기 명령 • 주어진 조건의 만족 여부에 따라 지정된 레이블의 주소로 분기 • ‘비교 명령’ & ‘조건 분기 명령’이 결합하여 구성 • C 언어의 IF 문장과 유사 • e.g) if (i <= 100) {…} else { … } • 비교 명령 : CMP • 조건 분기 명령 : JE / JA / JB … 시스템프로그래밍
조건 분기 명령 (2) • 비교 명령 • CMP [Register|Memory], [Register|Memory|상수] • 첫번째 operand와 두번째 operand의 크기를 비교하여 플래그 레지스터를 변경한다 • (첫번째 operand – 두번째 operand) 연산의 결과에 대해 플래그 레지스터 값을 설정 • 실제로는 operand의 값은 변경되지 않는다 • 예) CMP AX, 100 CMP AX, CX CMP CX, [BX+1] 시스템프로그래밍
조건 분기 명령 (3) • 플래그 레지스터(Flag Register) • 각 비트 별로 CPU의 상태값을 나타내는 제어 레지스터 • CF(Carry Flag) – 현재의 연산 결과로 자리올림(carry)이나 자리빌림(barrow)가 발생하면 1로 설정됨 • PF(Parity Flag) – 현재의 연산 결과에서 1인 비트수가 짝수 이면 1로 설정됨 • AF(Auxiliary Flag) – 현재의 연산 결과에서 하위 4(8)비트에서 자리올림(carry)이나 자리빌림(barrow)가 발생하면 1로 설정됨 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 시스템프로그래밍
조건 분기 명령 (4) • 플래그 레지스터(Flag Register) • ZF(Zero Flag) – 현재의 연산 결과가 0이면 1로 설정됨 • SF(Sign Flag) – 현재의 연산 결과에서 최상위 비트가 1이면 1로 설정됨(현재의 연산 결과가 음수가 되면 1로 설정됨) • OF(Overflow Flag) – 현재의 연산 결과에서 오버플로우나 언더플로우가 발생하면 1로 설정됨 • DF(Direction Flag) – 스트링 연산에서 레지스터의 증감 방향을 설정(1: 자동증가, 0:자동 감소) • IF(Interrupt Flag) – 외부 인터럽트 서비스 여부를 지정 (1:인터럽트 지원, 0: 인터럽트 무시) • TF(Trap Flag) – trap 지원 여부를 지정 시스템프로그래밍
조건 분기 명령 (5) • 플래그 레지스터 제어 명령 • 직접 플래그 레지스터의 비트 값을 변경하거나 플래그 레지스터의 값을 전송하는 명령 • STC(Set Carry Flag) / CLC(Clear Carry Flag) / CMC(Complement Carry Flag) • STD(Set Direction Flag) / CLD(Clear Direction Flag) • STI(Set Interrupt enable flag) / CLI(Clear Interrupt enable flag) • LAHF(Load AH from Flags) / SAHF(Store AH to Flags) • PUSHF(PUSH flags onto stack) / POPF(POP flags off stack) 시스템프로그래밍
조건 분기 명령 (6) • 플래그 레지스터 변경 명령 • 플래그 레지스터의 값은 비교명령(CMP)와 산술논리연산 명령의 실행에 의해서만 변경된다 • 전송 명령이나 분기 명령에 의해서는 플래그 레지스터 값이 변경 되지 않는다 • 예) MOV AX, 10 CMP AX, 10 SUB AX, 15 전송 명령에 의해서는 플래그 레지스터 값이 변경되지 않는다 ZF(zero Flag)가 1로 설정된다 SF(Sign Flag)가 1로 설정된다 시스템프로그래밍
조건 분기 명령 (7) • 조건 분기 명령 • 비교 명령이나 연산 명령에 의해 설정된 플래그 레지스터 값에 따라 지정된 레이블로 분기 여부를 결정하는 명령 • 비교 명령(CMP A, B)에 따른 조건 분기 명령 • A > B : JA / JNBE • A >= B : JAE / JNB • A = B : JE / JZ • A != B : JNE / JNZ • A <= B : JBE / JNA • A < B : JB / JNAE • 연산 명령의 결과에 따른 조건 분기 명령 • JS /JNS, JZ/JE, JNZ/JNE, JP/JNP, JB/JNB, JO/JNO 등 시스템프로그래밍
조건 분기 명령 (8) • 조건 분기 명령 예 • 예 1) MOV CX, 10 CMP CX, 100 JAE L1 • 예 2) MOV AX, 15 SUB AX, 20 JS L2 시스템프로그래밍
조건 분기 명령 (9) • 0부터 100까지 더하는 프로그램 CODE SEGMENT ASSUME CD:CODE, DS:CODE MOV AX, CODE MOV DS, AX ; MOV CX, 0 MOV AX, 0 L1: ADD AX, CX INC CX CMP CX, 100 JBE L1 MOV TOTAL, AX MOV AH, 4CH INT 21H ; TOTAL DW ? ; CODE ENDS END 시스템프로그래밍
무조건 분기 명령 (1) • JMP 명령 • 어떠한 조건과 상관없이 지정된 레이블의 주소로 분기 • 예) . . JMP L1 . . L1: ADD AX, BX . 시스템프로그래밍
무조건 분기 명령 (2) • MSG1의 문자열은 MSG2로 옮기는데 ‘$’자가 나타날 때까지 실행하고 옮겨진 문자의 개수를 저장하는 프로그램 CODE SEGMENT ASSUME CS:CODE, DS:DATA ; MOV AX, DATA MOV DS, AX MOV SI, OFFSET MSG1 MOV DI, OFFSET MSG2 MOV DX, 0 CONT: MOV AL, BYTE PTR [SI] CMP AL, ‘$’ JE EXIT MOV BYTE PTR [DI], AL INC SI INC DI INC DX JMP CONT EXIT: MOV NUMBER, DX MOV AH, 4CH INT 21H CODE ENDS ; DATA SEGMENT MSG1 DB ‘ABCDEFG$HIJKLMN’ MSG2 DB 16 DUP(?) NUMBER DW ? DATA ENDS END 시스템프로그래밍
무조건 분기 명령 (3) • 입력된 대문자 영문자를 소문자로 변환하여 출력하고, Ctrl+Z가 입력될 때까지 동작하는 프로그램 CODE SEGMENT ASSUME CS:CODE ; NEXT: MOV AH, 1 INT 21H CMP AL, 1AH JE EXIT CMP AL, ‘A’ JB L1 CMP AL, ‘Z’ JA L1 ADD AL, ‘a’-’A’ L1: MOV AH, 2 MOV DL, AL INT 21H JMP NEXT EXIT: MOV AH, 4CH INT 21H CODE ENDS END 시스템프로그래밍
서브루틴 호출(1) • 서브루틴(Subroutine) • 프로그램 중에서 반복적으로 사용되는 부분을 독립적으로 작성한 루틴 • 프로시저(Procedure) 라고도 함 • 서브루틴 사용의 이점 • 효과적인 프로그래밍이 가능 • 프로그램의 가독성 향상 • 프로그램 관리 및 보수 용이 시스템프로그래밍
서브루틴 호출(2) • 서브루틴 호출 • 서브루틴 호출 명령어 CALL subroutine-label • 현재의 PC 레지스터 값을 스택에 저장하고 지정된 주소로 분기한다 • 서브루틴 반환 명령어 RET • 스택에 저장된 반환 주소로 분기한다 MAIN: . . CALL SUB1 L1: . . . . SUB1: . . . . RET 시스템프로그래밍
서브루틴 호출(3) • 서브루틴 예제 프로그램 #1 • 0부터 9까지의 숫자를 출력하는 프로그램 MAIN SEGMENT ASSUME CS:MAIN ; MOV CX, 0 NEXT: CALL SUB1 INC CX CMP CX, 10 JB NEXT MOV AH, 4CH INT 21H ; SUB1: MOV DX, CX ADD DL, ‘0’ MOV AH, 2 INT 21H RET ; MAIN ENDS END 시스템프로그래밍
서브루틴 호출(4) • 서브루틴 예제 프로그램 #2 • AL 레지스터의 값을 ASCII 코드 16진수 값으로 화면에 출력하는 프로그램 MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; MOV AX, MAIN MOV DS, AX MOV AL, 3FH CALL PUTAL MOV AH, 4CH INT 21H ;--------------------------------------------------------- PUTAL: MOV BL, 10H MUL BL MOV LEVEL2, AH MOV AH, 0 MOV BL, 10H DIV BL MOV LEVEL1, AL MOV DL, LEVEL2 CALL PUTHEX MOV DL, LEVEL1 CALL PUTHEX 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 ? ; MAIN ENDS END 시스템프로그래밍
서브루틴 호출(5) • 프로시저 의사명령 • 서브루틴을 보다 구조적으로 표현하기 위해 사용하는 의사명령(Pseudo Code) • PROC ~ ENDP • 서브루틴 시작과 끝을 나타냄 subroutine-label PROC . 서브루틴 본체 코드 . subroutine-label ENDP 시스템프로그래밍
서브루틴 호출(6) • 서브루틴 예제 프로그램 #3 • 키보드에서 ASCII 코드를 입력하여 해당하는 ASCII 문자를 출력하는 프로그램 ;--------------------------------------------------------- GETAL: PROC MOV AH, 1 INT 21H CALL CVTAL JC GETEND MOV DH, AL MOV AH, 1 INT 21H CALL CVTAL JC GETEND MOV DL, AL MOV BH, 10H MOV AL, DH MUL BH ADD AL, DL GETEND: RET GETAL ENDP MAIN SEGMENT ASSUME CS:MAIN CR EQU 0DH LF EQU 0AH ; NEXT: CALL GETAL JC EXIT MOV DL, AL CALL PUTASC JMP NEXT EXIT: MOV AH, 4CH INT 21H 시스템프로그래밍
서브루틴 호출(7) • 서브루틴 예제 프로그램 #3 (계속) ;--------------------------------------------------------- PUTASC PROC MOV DH, DL MOV DL, ‘ ‘ MOV AH, 2 INT 21H MOV DL, DH MOV AH, 2 INT 21H MOV DL, CR MOV AH, 2 INT 21H MOV DL, LF MOV AH, 2 INT 21H RET PUTASC ENDP ; MAIN ENDS END ;--------------------------------------------------------- CVTAL PROC CMP AL, ‘0’ JB ERR1 CMP AL, ‘9’ JA SKIP1 SUB AL, ‘0’ JMP SKIP2 SKIP1: CMP AL, ‘A’ JB ERR1 CMP AL, ‘F’ JA ERR1 SUB AL, ‘A’-0AH SKIP2: CLC JMP CVTEND ERROR: STC CVTEND: RET CVTAL ENDP 시스템프로그래밍
서브루틴 호출(8) • 프로시저의 배치 • 프로시저는 코드 세그먼트 프로그램 내에서 어디든지 위치할 수 있다 • 프로시저가 코드 세그먼트의 시작 위치에 정의되어 있는 경우는 별도로 프로그램 시작 위치를 지정하여야 한다 • END 명령에서 프로그램 시작 위치를 지정 시스템프로그래밍
서브루틴 호출(9) • 프로그램 시작 위치 지정 예 MAIN SEGMENT ASSUME CS:MAIN EOF EQU 1AH ; GETCH PROC MOV AH, 8 INT 21H CMP AL, EOF JNE GETCHRET STC JMP GETCHEND GETCHRET: CLC GETCHEND: RET GETCH ENDP ; PUTCH PROC MOV AH, 2 INT 21H RET PUTCH ENDP ; START: CALL GETCH JC EXIT MOV DL, AL CALL PUTCH JMP START EXIT: MOV AH, 4CH INT 21H ; MAIN ENDS END START 시스템프로그래밍