- PC Assembly
- 데이터를 만들어주고 결과를 확인하기 위해 시스템 콜들을 이용
- 컴파일&실행 파일 만드는 법
- DOS Box 설치 / MASM 폴더 복사 / 폴더 Mount
- 윈도우 환경의 Editor로 편집
CODE SEGMENT
ASSUME CS:CODE ,DS : DATA
MOV AX, DATA
MOV DS, AX
MOV DL, SCR_1
MOV AH, 2
INT 21H
MOV CX, SCR_2
MOV DL, CH
MOV AH, 2
INT 21H
MOV DL, CL
MOV AH, 2
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
DATA SEGMENT
SCR_1 DB 'A' ; 1 Byte
SCR_2 DW 4243H ; 2 Byte
DATA ENDS
END
- Dos Box에서 Masm sample.asm
- Link ascii.obj
- 혹은 ml sample.asm
- 실행
- 위의 사진처럼 dir dtype이라는 명령어를 입력하면 exe파일이 생긴 것을 확인할 수 있다.
- cv /s dtype -> dtype만 호출해도 실행이 가능하지만 디버그를 하고 싶다면 cv /s를 앞에 붙여주어야 한다.
- 어셈블리에서 데이터들이 바뀌는 방식 등을 자세히 볼 수 있음
- Data type의 저장 방법
- 시스템 콜들의 비중이 매우 높은 것을 알 수 있음
- MASM에 의한 프로그램 개발 과정
- 여러 개의 파일을 묶어서 실행파일을 만들 수 있다.(동시 실행 가능)
- Object 파일들을 묶어놓은 것을 정적 라이브러리라고 한다.
- 소스는 달라도 오브젝트 파일로 만들어 묶으면 하나의 실행파일로 만들 수 있다.(exe, com)
- CPU의 명령어 실행 과정
- 명령어 인출(Instruction Fetch Cycle) : 실행할 명령어를 기억 장치로부터 읽어오는 과정
- 명령어 해독(Instruction Decode Cycle) : 읽어온 명령어를 해독하는 과정
- 데이터 인출(Data Fetch Cycle) : 데이터가 필요한 경우 데이터를 읽어오는 과정
- 실행 사이클(Execution Cycle) : 프로세서가 명령어를 실행하는 과정
- 8086 계열(16bit)
- Register : Data 저장, 연산 등을 위한 임시 기억 장치
- 각 레지스터는 자체의 특수한 용도와 제한점이 있다.
- 장점 : Memory(변수) 보다 access 속도가 빠르다.
- 단점 : 개수가 한정되어 있고, 용도가 제한적이다.
- 종류
- 범용 register : 8개(8086)
- 세그먼트 register : 4개(메모리 공간을 나타냄)
- 프로세서 컨트롤 register : 2개
- 총 14개의 register
- AX, BX, CX, DX : 범용 레지스터(General Purpose Register) - Accumulator Register, Base Register, Counter Register, Data Register
- SP, BP, SI, DI : 위치, 주소를 나타내는데 사용(포인터를 사용하기 위한 용도) - Stack Pointer, Base Pointer, Source Index, Destination Index
- 각각 16bit를 가지지만 8bit씩 가지고 사용하는 경우도 있음(AL + AH = AX) -> 공용체 구조
- Segment Register : {CS(Code Segment Register), DS(Data Segment Register)}, SS(Stack Segment Register), ES(Extra Segment Register)
- Processor Control Register : IP(Instruction Pointer - 어떤 위치의 명령어를 수행할 것인지), FL(Flag Register - 어떤 상태가 어떤 이유로 변했는지 알려주기 위한 flag)
- Register의 기능
- 어떤 메모리 공간을 나타낼때 사용하는 segment(덩어리)
- 그 세그먼트로부터 얼마나 떨어져 있는지 알려주는 offset
- CS(CODE Segment - 시작 주소)에서 IP가 가지고 있는 명령어의 위치를 실제 주소로 계산
- Data는 DS에 있는 offset값과 변위 값을 계산해서 사용
- SS:SP를 가지고 Stack동작
- 세그먼트 : offset이 정해진 형태
- Flag Register
- ex)Over flow가 발생했을 때 O라는 플래그가 1이 됨
- 8086의 주소 지정
- 8086 프로세서는 1MB까지의 memory를 취급(00000H~FFFFFH)
- 1MB = 2^20b => address data로 20 bit 필요
- 8086의 register는 16bit 크기이기 때문에 2개의 register를 조합
- 1개는 segment 1개는 offset으로 정함
- 세그먼트의 비트를 왼쪽으로 한 칸 옮긴 후(가상으로 0 하나를 붙임) 더함
- CS는 코드 세그먼트, DS는 데이터 세그먼트
- 0이 하나 붙어있기 때문에 1이 늘어났어도 실제로는 16이 늘어난 것
- 10000(segment) + 1000(offset) = 11000
- segment와 offset의 값에 따라 각자 값이 다르더라도 같은 주소 위치를 나타낼 수 있음
- 명령의 구성
- 뒤에서 앞으로 실행
- 의사 명령 : 예제 프로그램이 돌아가도록하는 MOV AX, BX을 제외한 L1과 같은 코드를 의미, 코드에 필요
- OP code(연산자)와 Operand(피연산자)는 반드시 필요
- Label은 특별한 경우에 붙이고 대부분 필요 없음
- Comment는 명령에 대한 간단한 설명을 붙이는 것 -> 어셈블하면 기계어 code로 변환되지 않고 단지 설명일 뿐
- 의사 명령어(Pseudo Code) : label이나 ASSUME, SEGMENT, ENDS, DB 등
- 프로그램의 초기 작성
- 세그먼트 선언
- Code Segment, Data Segment, Stack Segment 중 필요한 Segment를 선언
- Code Segment는 반드시 선언
- segment의 이름은 시작과 마지막이 같아야 한다.
- Code segment는 프로그램 code, data segment는 필요한 데이터, Stack segment는 필요한 크기의 메모리 영역을 확보한다.
- 실제 프로그램이 아니라 전체적인 프로그램 형태이기 때문에 의사명령어라 함 -> 프로그램을 만들어가는 과정에 사용하는 것, 적용될 때는 추가적인 것들을 더 사용해야 함
- ASSUME 의사 명령어
- ASSUM에 CS는 CODE에 있고 DS는 DATA에 있다고 가정해줌
- 프로그램 전체가 끝나면 END를 써줌 -> ENDS는 Segment가 끝났다는 의미
- 예제
- Code 세그먼트 하나만 있음
- Data, stack, 엑스트라 세그먼트 모두 없음
- ASSUME이 시작점으로 잡힘, DS는 자동으로 잡히지 않음
- 명령어 수행
- 명령어의 구성과 기계어 생성
- 인텔 사이트에서 명령어 세트 찾을 수 있음
- 구글에서 24319102.pdf를 검색하는 것이 빠를 수 있음
- MOV의 경우
- 9개의 형태를 가짐
- Operand는 2개
- imm은 실제 숫자, reg16은 16비트 레지스터, segreg는 세그먼트 레지스터
- MOV는 뒤의 값을 앞의 값에 복사하라는 명령어
- imm을 imm으로 넣지 못함, mem에서 바로 mem으로 옮기지 못함, segreg에서 segreg로 바로 옮기지 못함
- 여러 CPU에 따른 명령어들
- MOV reg,reg는 보통 2 클럭이면 처리가 됨, immed to reg는 4 클럭으로 처리 -> 어디에서 어디로 가져오느냐에 따라 클럭 수가 바뀜
- 곱셈(MUL)은 MOV보다 매우 많은 시간이 소요됨 -> 따라서 보통 shift연산을 함
- 해독(Decoding)
- 9가지에 따라 세부적으로 다시 나뉘어짐
- 해석하는 과정이 필요
- 처음 6비트는 opcode(명령어)로 사용, d는 direction, w는 word
- mod는 mode(뒤에 있는 것들을 어떻게 할 것인지), reg는 레지스터, rm은 레지스터 혹은 메모리
- 예시
- MOD 자리에 00을 쓰면 R/M Table 1에서 사용, 01 10 11 모두 테이블이 정해져 있음
- ex) MOV AL, BL
- reg에서 reg는 100010이라는 OP코드를 가지고 있음
- BL -> AL의 연산에서 d가 0이면 REG에서 R/M으로 가는 것이므로 BL은 REG에 AL은 R/M에 넣는다.
- d가 1이면 R/M에서 REG로의 연산이 되어 BL을 R/M에 넣고 AL을 REG에 넣는다.
- 이 예시는 d가 1일 경우이다.
- 위의 REG filde에서 BL은 011, AL은 000이므로 각 자리에 값을 넣어준다.
- reg -> reg이므로 mod는 11
- d는 1, w는 byte단위로 사용 중이므로 0
- 이를 모두 이어서 4개씩 끊어 읽으면 8AC3이 됨
- ex) MOV AL, BL 반대(d가 0일 경우)
- 다른 것들도 해보자
'운영체제' 카테고리의 다른 글
[12주차]chapter 6 : Process Synchronization(프로세스 동기화) (0) | 2019.05.21 |
---|---|
[11주차]간단한 어셈블리 프로그래밍 (0) | 2019.05.14 |
Chapter 5 - CPU Scheduling(9주차) (0) | 2019.04.30 |
Chapter 5 - CPU Scheduling - 7주차 (0) | 2019.04.13 |
Chapter 5 - CPU Scheduling (0) | 2019.04.09 |