섹터 읽기
include <stdio.h>
int main(int argc, char* argv[])
{
int iTotalSectorCount = 1024;
int iSectorNumber = 2;
int iHeadNumber = 0;
int iTrackNumber = 0;
//실제 이미지를 복사할 어드레스(물리주소)
char* pcTargetAddress = (char*)0x10000;
while(1)
{
//전체 섹터 수를 하나씩 감소시키면서 0이 될때까지 섹터를 복사
if(iTotalSectorCount == 0)
{
break;
}
iTotalSectorCount = iTotalSectorCount - 1;
//1섹터를 읽어들여서 메모리 어드레스에 복사
//BIOSReadOneSector: BIOS 섹터읽기 기능을 호출하는 임의의 함수
if(BIOSReadOneSector(iSectorNumber, iHeadNumber, iTrackNumber, pcTargetAddress) == ERROR)
{
HandleDiskError();
}
//1섹터는 512(0x200) 바이트이므로, 복사한 섹터 수만큼 어드레스 증가
pcTargetAddress = pcTargetAddress + 0x200;
//섹터->헤드->트랙 순으로 번호 증가
iSectorNumber = iSectorNumber + 1; if(iSectorNumber < 19)
{
continue;
}
iHeadNumber = iHeadNumber ^ 0x01;
//헤드의 번호는 0과 1이 반복되므로 XOR 연산을 이용
iSectorNumber = 1;
if (iHeadNumber != 0)
{
continue;
}
iTrackNumber = iTrackNumber + 1;
}
return 0;
} void HandleDiskError()
{
printf("DISK Error!");
while(1);
}
C++
복사
어셈블리어 섹션 코딩
TOTALSECTORCOUNT:
dw 1024 ; 부트로더를 제외한 os이미지의 크기
; 최대 1151섹터(0x90000byte)까지 가능
SECTORNUMBER:
db 0x02 ; os이미지가 시작하는 섹터번호를 저장하는 영역 HEADNUMBER:
db 0x00 ; os이미지가 시작하는 헤드번호를 저장하는 영역 TRACKNUMBER:
db 0x00 ; os이미지가 시작하는 트랙번호를 저장하는 영역
; 디스크의 내용을 메모리로 복사할 어드레스(ES:BX)를 0x10000으로 설정
mov si, 0x1000 ; os이미지를 복사할 어드레스(0x10000)를
; 세그먼트 레지스터 값으로 변환
mov es, si ; ES세그먼트 레지스터에 값 설정
mov bx, 0x0000 ; BX레지스터에 0x0000을 설정하여 복사할
; 어드레스를 0x1000:0000(0x10000)으로 최종 설정
mov di, word [ TOTALSECTORCOUNT ] ; 복사할 os이미지의 섹터 수를 DI레지스터에 설정
READATA: ; 디스크를 읽는 코드의 시작
; 모든 섹터를 다 읽었는지 확인
cmp di, 0 ; 복사할 os 이미지의 섹터 수를 0과 비교
je READEND ; 복사할 섹터 수가 0이라면 다 복사 했으므로
READEND로 이동 sub di, 0x1 ; 복사할 섹터 수를 1감소
;;;;;;;;;;;;;;;;;;;;;;;;;
; BIOS Read Function 호출
;;;;;;;;;;;;;;;;;;;;;;;;;
mov ah, 0x02 ; BIOS 서비스 번호 2(Read Sector)
mov al, 0x01 ; 읽을 섹터 수는 1
mov ch, byte [ TRACKNUMBER ] ; 읽을 트랙 번호 설정
mov cl, byte [ SECTORNUMBER ] ; 읽을 섹터 번호 설정
mov dh, byte [ HEADNUMBER ] ; 읽을 헤드 번호 설정
mov dl, 0x00 ; 읽을 드라이브 번호(0=Floppy)설정
int 0x13 ; 인터럽트 서비스 수행
jc HANDLEDISKERROR ; 에러가 발생했다면 HANDLEDISKERROR로 이동
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 복사할 어드레스와 트랙, 헤드, 섹터 어드레스 계산
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
add si, 0x0020 ; 512(0x200)바이트만큼 읽었으므로, 이를 세그먼트 레지스터 값으로 변환
mov es, si ; ES 세그먼트 레지스터에 더해서 어드레스를 한 섹터만큼 증가
; 한 섹터를 읽었으므로 섹터 번호를 증가시키고 마지막 섹터(18)까지 읽었는지 판단
; 마지막 섹터가 아니면 섹터 읽기로 이동해서 다시 섹터 읽기 수행
mov al, byte [ SECTORNUMBER ] ; 섹터번호를 AL 레지스터에 설정
add al, 0x01 ; 섹터번호를 1 증가
mov byte [ SECTORNUMBER ], al ; 증가시킨 섹터번호를 SECTORNUMBER에 다시 설정
cmp al, 19 ; 증가시킨 섹터번호를 19와 비교
jl READDATA ; 섹터번호가 19미만이라면 READDATA로 이동
; 마지막 섹터까지 읽었으면(섹터번호가 19이면) 헤드를 토글(0->1, 1->0)하고,
; 섹터번호를 1로 설정
xor byte [ HEADNUMBER ], 0x01 ; 헤드번호를 0x01과 XOR하여 토글(0->1, 1->0)
mov byte [ SECTORNUMBER ], 0x01 ; 섹터 번호를 다시 1로 설정
; 만약 헤드가 1->0으로 바뀌었으면 양쪽 헤드를 모두 읽은 것이므로 아래로 이동하여
; 트랙 번호를 1증가
cmp byte [ HEADNUMBER ], 0x00 ; 헤드번호를 0x00과 비교
jne READDATA ; 헤드번호가 0이 아니면 READDATA로 이동
; 트랙을 1증가시킨 후, 다시 섹터 읽기로 이동
add byte [ TRACTNUMBER ], 0x01 ; 트랙번호를 1증가
jmp READDATA ; READDATA로 이동 READEND:
HANDLEDISKERROR: ; 에러를 처리하는 코드
;;;생략;;;
jmp $
C
복사