<증가, 감소 명령>
■ INC (INCrement)
-> 형식 : INC OP
reg //Segment register 사용 불가
mem
-> 기능 : OP ← OP+1
ex) MOV AX, 5
INC AX //결과 AX = 6
■ DEC (DECrement)
-> 형식 : DEC OP
reg
mem
-> 기능 : OP ← OP-1
ex) MOV DL, 10
DEC DL //결과 DL = 9
<키 입력 방법>
■ 에코(echo) 있는 입력 //에코는 내가 입력한 값을 알려주는 것
MOV AH, 1
INT 21H
//Function code가 1인 System call
//입력된 문자의 ASCII 코드는 AL에 저장
■ 에코(echo) 없는 입력
MOV AH, 8
INT 21H
//Function code가 8인 System call
//입력된 문자의 ASCII 코드는 AL에 저장
<예시코드 366.asm>
CODE SEGMENT
ASSUME CS:CODE, DS:CODE
MOV AX, CODE
MOV DS, AX
MOV AH, 8
INT 21H ; 키입력, AL에 저장
MOV KEEP, AL
MOV DL, KEEP ; 입력 결과를 변수에 저장
ADD DL, 1
MOV AH, 2
INT 21H
MOV AH, 4CH
INT 21H
KEEP DB ?
CODE ENDS
END
<비교 명령어>
■ CMP(Compare) 명령어
-> 형식 : CMP OP1, OP2
reg reg
reg mem
reg imm
mem reg //Memory 끼리는 안된다. mem mem (x)
mem imm
-> 기능 : OP1 - OP2의 결과에 따라 Flag register 변화, operand 내용 불변
//Flag register의 상태에 따라 조건 분기 명령 수행, 즉 Flag에 영향을 준다.
ex) CMP CX, 10 //CX 값이 10이면 ZF=1
■ TEST 명령어
-> 형식 : TEST OP1, OP2
reg reg
reg mem
reg imm
mem reg //Memory 끼리는 안됨 mem mem (x)
mem imm
-> 기능 : OP1 AND OP2의 결과에 따라 Flag register의 변화, operand 내용 불변
//Bit 단위의 논리곱
//Flag register의 상태에 따라 조건 분기 명령 수행
ex) TEST CL, 80H
//80H = 1000 0000(2), CL의 MSB가 0이면 ZF=1
//AND 연산의 특징
0 AND x = 0
1 AND x = x
<분기 명령어의 비교>
<분기 명령어>
■ 무조건 분기 명령어 : JMP label
-> 무조건 label로 분기(Jump)
ex) CASE1: ... //label
JMP CASE1 //goto label
<예제코드 372.asm>
CODE SEGMENT
ASSUME CS: CODE
NEXT: MOV AH, 1 ;1문자 입력
INT 21H
MOV DL, AL
INC DL
MOV AH, 2 ;1문자 출력
INT 21H
JMP NEXT ;무조건분기
MOV AH, 4CH
INT 21H
CODE ENDS
END
//계속 NEXT라벨로 분기한다.
■ 조건 분기 명령어
-> 조건을 만족하면 label로 분기, 만족하지 않으면 무시
//JBE는 작거나 같을 때 레이블 실행
■ 조건 분기 명령의 정리
■ Flag register를 이용한 분기
■ 대문자 → 소문자 변환 프로그램
<375Atoa.asm>
CODE SEGMENT ; 소문자를 대문자로 변환해주는 프로그램
ASSUME CS: CODE
NEXT: MOV AH, 1 ;AL에 1문자 키보드 입력(echo)
INT 21H ;MOV AH,8 → No echo
CMP AL, 20H ;ASCII 코드 20H → space bar
JE EXIT ;프로그램 종료
CMP AL, 'A'
JB PRINT ;'A'보다 작으면 그대로 출력
CMP AL, 'Z'
JA PRINT ;'Z'보다 크면 그대로 출력
ADD AL, 'a'-'A' ;대문자이면 소문자로 변환
PRINT:MOV AH, 2 ; 1문자 출력(DL)
MOV DL, AL
INT 21H
JMP NEXT
EXIT: MOV AH, 4CH ; 프로그램 종료
INT 21H
CODE ENDS
END
<반복 명령어>
■ LOOP 명령어 : LOOP label
-> CX ← 반복할 횟수, 자동적으로 1씩 감소하면서, CX = 0 될 때까지 반복
//FOR문과 유사하다.
//LOOP 명령어는 CX레지스터의 값을 1씩 감소시키면서 실행한다.
ex) MOV AX, 0
MOV CX, 10 ; 반복 횟수
NEXT: ADD AX, CX
LOOP NEXT
ex) MOV AX, 0
MOV CX, 10
NEXT: ADD AX, CX
DEC CX
JA NEXT
■ LOOPE / LOOPZ (Loop while Equal)
-> 상한을 CX번으로 정해 놓고, 다른 것이 나타날 때 까지 반복한다.
■ LOOPNE / LOOPNZ (Loop while Not Equal)
-> 상한을 CX번으로 정해 놓고, 같은 것이 나타날 때까지 반복
■ REP (REPete) 명령어
-> 하나의 명령어만을 반복, CX ← 반복 횟수
<스택의 동작>
■ Stack의 정의
-> 메모리의 한 영역으로 데이터를 임시 저장했다가(PUSH), 다시 불러들일 때(POP) 사용
ex) 동전 케이스
cf) Stack : LIFO(Last In First Out) 구조
Queue : FIFO(First In First Out) 구조
■ Stack의 사용
-> 서브루틴에서 복귀할 주소 저장
-> 임시 데이터 저장
-> 서브루틴의 인수 전달
■ SS = CS (default)
■ PUSH와 POP 명령어
-> 형식:
PUSH OP ; OP를 stack에 저장
POP OP ; Stack의 데이터를 OP에 저장
reg(16bit)
mem(16bit) //반드시 16bit
sreg(segment register)
-> IP, SS, SP는 PUSH 불가능(IP는 자동으로)
-> PUSH와 POP의 개수 일치, 순서 반대로
-> PUSHF : Flag register를 stack에 저장
POPF : Stack의 데이터를 Flag register의 값으로
-> 16bit (2byte) 단위로 저장
<385.asm>
CODE SEGMENT
ASSUME CS:CODE
MOV AX, 1234H
MOV BX, 5678H ;초기값 ;SP=0
PUSH AX ;SP = FFFEH
PUSH BX ;SP = FFFCH ;Stack에 저장
PUSHF ;SP = FFFAH
MOV AX, 2468H
MOV BX, 2468H
SUB AX, BX ;값 변화
POPF ;SP = FFFCH ;PUSH의 역순
POP BX ;SP = FFFEH ;Stack에서 복구
POP AX ;SP = 0
MOV AH,4CH
INT 21H
CODE ENDS ;MASM에는 지역변수가 없고
END ;모두 전역변수이므로 지역변수
;역할이 필요할 때 STACK을 이용
<서브루틴 사용법>
■ Subroutine
-> 프로그램 중 일부를 독립된 부분으로 작성한 후 main routine에서 호출(call)해서 사용 //여러 번 호출하는 루틴
-> 복귀할 주소를 stack에 자동 저장
-> 서브루틴 수행 후 호출한 다음 번지로 복귀
■ CALL과 RET(RETurn)
-> 형식:
■ ex) 0~9 숫자를 출력(문자로 바꾸어서)
<382.asm>
CODE SEGMENT
ASSUME CS:CODE
MOV CL, 0 ;초기화
NEXT: CALL PUTNUM ;subroutine 호출
INC CL ;CL = CL+1
CMP CL, 10 ;CL이 10보다
JB NEXT ;작으면(Below) NEXT로 JUMP
MOV AH, 4CH
INT 21H
PUTNUM:
MOV DL, CL
ADD DL, '0' ;숫자를 문자로 변환('0'=30H)
MOV AH, 2
INT 21H
RET
CODE ENDS
END
■ ex) 16진수(8비트 register 값)를 화면에 표시
<390putal.asm>
CODE SEGMENT
ASSUME CS:CODE
MOV AX, CS
MOV DS, AX
MOV AL, 3FH ;출력할 숫자
CALL PUTAL ;PUTAL 호출
MOV AH, 4CH
INT 21H
PUTAL:
MOV BL, 10H
MUL BL ;AX = 03F0H
MOV LEVEL2, AH ;상위보존
MOV AH, 0 ;AX=00FOH
DIV BL ;AL=0FH
MOV LEVEL1, AL ;하위보존
MOV DL, LEVEL2
CALL PUTHEX ;PUTHEX호출
MOV DL, LEVEL1
CALL PUTHEX ;PUTHEX호출
RET ;return
PUTHEX:
CMP DL, 0AH
JAE HEX
ADD DL, '0'
JMP PRINT
HEX:
ADD DL, 'A'-0AH
PRINT:
MOV AH, 2
INT 21H
RET
LEVEL1 DB ?
LEVEL2 DB ?
CODE ENDS
END
<PROC에 의한 서브루틴 작성>
■ PROC ... ENDP
-> 서브루틴을 보다 구조적으로 표현하는 방법
-> 형식:
프로시져_이름 PROC [속성] //생략 가능
...
프로시져_이름 ENDP //END Procedure
-> 속성
NEAR : 동일 세그먼트 내에 존재(default)
FAR : 다른 세그먼트에 존재
<392proc.asm>
CODE SEGMENT
ASSUME CS:CODE
START: MOV AX, CS ;시작 번지를 가리키는 라벨
MOV DS, AX
MOV AL, 3FH
CALL PUTAL ;서브루틴 호출
MOV AH, 4CH
INT 21H
PUTAL PROC ;서브루틴 시작
MOV BL, 10H
MUL BL ;AX = 03F0H
MOV LEVEL2, AH ;상위보존
MOV AH, 0 ;AX=00FOH
DIV BL ;AL=0FH
MOV LEVEL1, AL ;하위보존
MOV DL, LEVEL2
CALL PUTHEX ;PUTHEX호출
MOV DL, LEVEL1
CALL PUTHEX ;PUTHEX호출
RET ;reuturn
PUTHEX:
CMP DL, 0AH
JAE HEX
ADD DL, '0'
JMP PRINT
HEX:
ADD DL, 'A'-0AH
PRINT:
MOV AH, 2
INT 21H
RET
LEVEL1 DB ?
LEVEL2 DB ?
PUTAL ENDP ;서브루틴 끝
CODE ENDS
END START ;시작번지를 지정, 프로시져등으로 인해 메인루틴의 순서가 바뀌는 경우 꼭 필요
'운영체제' 카테고리의 다른 글
운영체제)#12 Process Synchronization (0) | 2020.06.01 |
---|---|
운영체제) #10 System Call의 이해: 어셈블리어(PC버전) (0) | 2020.05.31 |