장 – 8
C를 사용한 Disk-BIOS 기능 및 인터럽트 처리
소개
이번 장에서는 Disk-BIOS의 중요한 기능과 간단하고 짧은 방법으로 C 프로그램에서 인터럽트를 사용하고 처리할 수 있는 자유를 제공하는 다른 중요한 기능에 대해 논의하겠습니다. 이러한 기능은 데이터 복구 및 디스크 문제 해결 프로그래밍의 기초입니다. 이것이 C 언어를 "고수준 어셈블리 언어"로 만드는 특징입니다 .
biosdisk와 _bios_disk의 기능
이 두 가지 기능은 데이터 복구 및 디스크 문제 해결 프로그래밍 목적에 가장 중요합니다. 우리는 이러한 기능을 가장 자주 사용할 것입니다.
이 두 가지 기능은 BIOS 디스크 드라이브 서비스이며 bios.h에 정의되어 있습니다. 여기서 biosdisk는 파일 수준 아래의 원시 섹터에서 작동합니다. 이러한 기능을 약간이라도 부주의하게 사용하면 하드 드라이브에 있는 파일과 디렉토리의 내용이 파괴될 수 있습니다. biosdisk와 _bios_disk 함수는 둘 다 인터럽트 0x13을 사용하여 디스크 작업을 BIOS에 직접 전달합니다. _bios_disk 함수는 프로그램에서 다음과 같이 선언됩니다.
서명되지 않은 _bios_disk(서명되지 않은 명령, 구조체 diskinfo_t *dinfo);
BIOS 디스크 기능에 대한 선언은 다음과 같습니다.
int biosdisk(int cmd, int 드라이브, int 헤드, int 트랙,
int sector, int nsects, void *buffer);
다음 표에서는 이러한 매개변수의 의미에 대해 설명합니다.
매개변수 |
기능 |
그것은 무엇인가 또는 무엇을 하는가 |
cmd |
둘 다 |
읽기, 쓰기, 검사 등 수행할 작업을 지정합니다. (아래 cmd 설명 참조) |
디포 |
_바이오스_디스크 |
작업에 필요한 나머지 매개변수를 포함하는 diskinfo_t 구조를 가리킵니다. (아래의 diskinfo_t 구조 설명을 참조하세요) |
자동차를 운전하다 |
바이오스디스크 |
사용될 디스크를 지정합니다(0은 a:, 1은 b:, 첫 번째 물리적 하드 디스크는 0x80, 두 번째는 0x81 등). |
머리
궤적 섹터
|
바이오스디스크 |
이는 작업이 시작되어야 하는 시작 구역의 위치를 정의합니다. |
곤충 |
바이오스디스크 |
읽고, 쓰고, 검사할 섹터의 수 |
완충기 |
바이오스디스크 |
데이터를 읽거나 쓸 메모리 주소. |
두 함수 모두에서 데이터는 섹터당 512바이트의 버퍼에 읽혀지고 쓰여집니다. 이는 하드 드라이브의 논리적 섹터 크기이며, 두 함수의 반환 값은 BIOS 호출 INT 0x13H에 의해 설정된 AX 레지스터 값입니다.
함수가 성공하면 상위 바이트 = 0, 즉 성공적인 완료를 의미하고 하위 바이트에는 읽은 섹터, 쓴 섹터 또는 검증된 섹터의 개수 등이 포함됩니다.
하지만 오류가 발생하여 함수가 성공적으로 실행되지 않으면 상위 바이트 값은 다음 오류 코드 중 하나와 일치하게 됩니다. 해당 오류 코드는 다음 표에 설명되어 있습니다.
값 |
설명 |
0x00 |
성공적으로 완료되었습니다(오류가 아닙니다!!) |
0x01 |
나쁜 팀 |
0x02 |
주소 라벨을 찾을 수 없습니다 |
0x03 |
쓰기 보호된 디스크에 쓰기를 시도합니다. |
0x04 |
섹터를 찾을 수 없습니다 |
0x05 |
재설정 실패(하드 드라이브) |
0x06 |
마지막 작업 이후 디스크가 수정되었습니다. |
0x07 |
드라이브 매개변수 작업을 실행하지 못했습니다. |
0x08 |
직접 메모리 액세스(DMA) 오버플로 |
0x09 |
64K 경계를 가로질러 DMA를 수행하려고 시도합니다(데이터 경계 오류 또는 섹터 >80H) |
0x0A |
불량 섹터가 감지되었습니다 |
0x0B |
잘못된 트랙이 감지되었습니다 |
0x0C |
지원되지 않는 트랙 |
0x0D |
포맷 시 섹터 수가 올바르지 않음(PS/2 하드 드라이브) |
0x0E |
제어 데이터 주소 표시 감지됨(하드 디스크) |
0x0F |
DMA 중재 수준이 범위를 벗어남(하드 드라이브) |
0x10 |
디스크를 읽을 때 CRC/ECC가 올바르지 않습니다. |
0x11 |
CRC/ECC 데이터 수정 오류(실제로는 오류가 아님) |
0x20 |
컨트롤러가 고장났습니다 |
0x31 |
드라이브에 미디어가 없습니다(IBM/MS INT 13 확장) |
0x32 |
CMOS에 저장된 잘못된 디스크 유형(Compaq) |
0x40 |
검색 작업이 실패했습니다. |
0x80 |
첨부파일이 응답하지 않았습니다 |
0xAA |
디스크가 준비되지 않았습니다(하드 디스크만 해당) |
0xB0 |
볼륨이 디스크에 잠기지 않았습니다(INT 13 확장) |
0xB1 |
디스크의 볼륨이 잠겼습니다(INT 13 확장) |
0xB2 |
제거할 수 없는 볼륨(INT 13 확장) |
0xB3 |
사용량 (INT 13 확장) |
0xB4 |
잠금 개수 초과(INT 13 확장) |
0xB5 |
유효한 throw 요청을 수행하지 못했습니다(INT 확장 13) |
0xBB |
지정되지 않은 오류가 발생했습니다(하드 드라이브만 해당) |
0xCC |
녹음 오류가 발생했습니다 |
0xE0 |
상태 등록 오류 |
0xFF |
Operation Sense가 실패했습니다. |
아래 표는 cmd 매개변수에 의해 수행되는 작업 명령을 보여줍니다. 우선, 두 함수의 일반적인 동작을 살펴보겠습니다.
바이오스디스크 |
_바이오스_디스크 |
그는 무엇을 하고 있나요? |
0 |
_디스크_재설정 |
디스크 시스템을 재설정하여 드라이브 컨트롤러가 하드 재설정을 수행하도록 강제합니다. 다른 모든 매개변수는 무시합니다. |
1 |
디스크 상태 |
마지막 디스크 작업의 상태를 반환합니다. 다른 모든 매개변수는 무시합니다. |
2 |
_디스크_읽기 |
하나 이상의 디스크 섹터를 메모리로 읽습니다. |
3 |
디스크 쓰기 |
메모리에서 하나 이상의 디스크 섹터를 씁니다. |
4 |
_디스크_검증 |
하나 이상의 섹터를 확인합니다. |
5 |
_디스크_포맷 |
트랙을 포맷합니다 |
cmd = 0, 1, 2, 3, 4,5 또는 cmd = _DISK_RESET, _DISK_STATUS, _DISK_READ, _DISK_WRITE, _DISK_VARIFY, _DISK_FORMAT을 사용할 수 있으며 두 옵션 모두 동일한 효과를 갖지만 cmd = 5 대신 cmd = _DISK_FORMAT과 같이 단어 옵션을 사용하는 습관을 들이는 것이 좋습니다. 이렇게 하면 cmd에 잘못된 명령 번호를 입력하여 발생할 수 있는 오류를 방지하는 데 도움이 될 수 있습니다.
biosdisk 또는 _bios_disk 함수 선언에서 cmd = _DISK_RESET을 제공하면 함수는 다른 모든 매개변수를 무시하고 디스크 시스템을 재설정하고 _DISK_STATUS는 다른 모든 매개변수를 무시하고 마지막 디스크 작업의 상태를 반환합니다.
cmd =_DISK_READ, _DISK_WRITE 또는 _DISK_VERIFY(2, 3 또는 4)의 경우 biosdisk 및 _bios_disk 함수는 아래에 표시된 다른 매개변수도 사용합니다.
매개변수 |
그것이 하는 일 |
헤드
트랙
섹터 |
이 세 가지는 지정된 작업에 대한 시작 섹터의 위치를 지정합니다. (최소 가능한 값은 head = 0, track = 0, sector = 1일 수 있음) |
섹터 |
이것은 읽거나 쓸 섹터의 수를 지정합니다. |
완충기 |
데이터를 읽고 쓸 버퍼를 가리킨다 |
cmd의 값이 = 5(_DISK_FORMAT)이면 biosdisk와 _bios_disk는 표의 설명에 따라 다음 매개변수를 사용합니다. _DISK_FORMAT을 사용하는 동안 항상 주의를 기울이고 무엇을 할 것인지 아는 것이 좋습니다. 지식이 부족하거나 작은 실수라도 큰 데이터 손실에 직면하게 될 수 있습니다.
매개변수 |
그것이 하는 일 |
헤드
트랙 |
이것은 포맷할 트랙의 위치를 지정합니다. |
완충기 |
이는 명명된 트랙에 기록될 섹터 헤더 테이블을 가리킵니다. |
cmd에는 biosdisk 함수에서만 사용되는 몇 가지 추가 값이 있습니다. cmd의 이러한 값은 XT, AT, PS/2 및 호환 제품에만 허용됩니다. 값은 다음 표에 설명되어 있습니다.
cmd |
그것이 무엇을 하는가 |
6 |
트랙을 포맷하고 불량 섹터 플래그를 설정합니다. |
7 |
특정 트랙에서 시작하여 드라이브를 포맷합니다. |
8 |
버퍼의 처음 4바이트에 현재 드라이브 매개변수를 반환합니다. |
9 |
드라이브 쌍 특성을 초기화합니다. |
10 |
긴 읽기(섹터당 512바이트와 4개의 추가 바이트) |
11 |
긴 쓰기(섹터당 512바이트와 4개의 추가 바이트) |
12 |
디스크 탐색이 되나요? |
13 |
대체 디스크 재설정 |
14 |
섹터 버퍼를 읽습니다 |
15 |
섹터 버퍼를 씁니다 |
16 |
명명된 드라이브가 준비되었는지 테스트합니다. |
17 |
드라이브를 재보정합니다 |
18 |
컨트롤러 RAM 진단 |
19 |
드라이브 진단 |
20 |
컨트롤러 내부 진단 |
diskinfo_t 구조
diskinfo_t 구조는 _bios_disk 함수에서 사용됩니다. 구조에 대한 설명은 다음과 같습니다.
구조체 diskinfo_t {
서명되지 않은 드라이브, 헤드, 트랙, 섹터, nsectors;
void far *버퍼;
};
여기서 drive는 사용할 디스크 드라이브를 지정합니다. 하드 디스크의 경우 디스크 파티션이 아닌 물리적 드라이브가 지정된다는 점을 항상 기억하세요. 파티션을 작동하려면 애플리케이션 프로그램도 해당 디스크 자체의 파티션 테이블 정보를 해석해야 합니다.
head, track 및 sector의 값은 작업의 시작 섹터 위치를 지정합니다. nsectors는 읽거나 쓸 섹터 수를 지정하고 buffer는 데이터를 읽고 쓸 버퍼를 가리킵니다. cmd의 값에 따라 diskinfo_t 구조의 다른 매개변수가 필요할 수도 있고 필요하지 않을 수도 있습니다.
biosdisk 및 _bios_disk 함수에 사용되는 디스크 드라이브 사양 값은 다음 표에 나와 있습니다.
드라이브 가치 |
사용할 디스크 드라이브 |
0 |
최초의 플로피 디스크 드라이브 |
1 |
두 번째 플로피 디스크 드라이브 |
2 |
세 번째 플로피 디스크 드라이브 |
.... |
(등) |
0x80 |
첫 번째 하드 디스크 드라이브 |
0x81 |
두 번째 하드 디스크 드라이브 |
0x82 |
세 번째 하드 디스크 드라이브 |
.... |
(등) |
이론은 그만! 이제 몇 가지 실용적인 것과 이러한 기능의 몇 가지 예를 살펴보겠습니다. 다음 예는 플로피의 네 트랙 양쪽의 섹터를 읽고 사용자가 지정한 파일에 내용을 저장합니다. 디스크에서 파일을 삭제했는지는 중요하지 않습니다. 프로그램이 디스크 표면을 직접 읽고 있기 때문입니다.
삭제된 데이터를 보려면 완전히 포맷된 플로피 디스크를 가져와 .c 프로그램 코딩이나 기타 텍스트 파일(파일 내용을 이해할 수 있도록)과 같은 텍스트 파일을 복사하는 것이 더 좋습니다. 이 파일은 약 73KB(4개 트랙, 2면, 각 트랙의 18개 섹터에 저장된 데이터. 각 섹터는 512바이트)를 차지합니다. 이 프로그램은 예를 보여주기 위해 개발되었습니다. 그러나 데이터를 복구할 준비가 되도록 변경하고 개발할 수 있습니다.
/* 플로피의 4개 트랙(0, 1, 2, 3)을 읽고 지정된 파일에 내용을 쓰는 프로그램 */
#include <bios.h>
#include <stdio.h>
#include<conio.h>
void 메인(void)
{
int 헤드,트랙;
int 결과, i, 섹터;
char 파일명[80];
char *버퍼;
구조체 diskinfo_t dinfo;
정적 char dbuf[512];
파일 *tt;
영어: clrscr();
/// 드라이브가 준비되었는지 확인 \\\
if(!(바이오스디스크(4,0,0,0,0,1,버퍼) & 0x02))
{
printf("드라이브 A: 준비 안 됨:\n 드라이브 A에 디스크를 넣으세요:
그리고 아무 키나 누르세요\n");
getch();
}
/* 디스크 섹터의 데이터를 저장할 파일 이름을 가져옵니다. */
printf("\n대상 파일 이름과 전체 경로를 입력하세요.
데이터를 저장하려면 \n\n >");
gets(파일 이름);
if((tt= fopen(파일 이름, "wb"))==NULL)
{
printf("파일을 열 수 없습니다!!!");
getch();
}
트랙=0;트랙<4;트랙++)
{
for(머리=0; 머리<=1; 머리++)
{
섹터=1;섹터<=18;섹터++)
{
dinfo.drive = 0; /* A에 대한 드라이브 번호 */
dinfo.head = head; /* 디스크 헤드 번호 */
dinfo.track = track; /* 트랙 번호 */
dinfo.sector = sector; /* 섹터 번호 */
dinfo.nsectors = 1; /* 섹터 수 */
dinfo.buffer = dbuf; /* 데이터 버퍼 */
/// 상태 표시 \\\
gotoxy(10,10); printf("데이터 읽기 중: Head=%d
트랙=%d 섹터=%d",
머리, 트랙, 부문);
fprintf(tt, "\n 읽은 데이터: Head=%d Track=%d Sector=%d\n",
머리, 트랙, 부문);
/// 지정된 섹터 읽기 \\\
결과 = _bios_disk(_DISK_READ, &dinfo);
/// 지정된 파일에 내용을 저장합니다 \\\
if ((결과 & 0xff00) == 0)
{
i=0;i<512;i++에 대하여
fprintf(tt, "%c",dbuf[i] & 0xff);
}
/* 섹터를 읽는 동안 오류가 발생하면 화면과 파일에 오류 메시지를 인쇄합니다. */
또 다른
{
printf("\n Head= %d Track= %d에서 읽을 수 없습니다.
섹터 = %d\n",헤드,트랙,섹터);
fprintf(tt, "\n Head= %d Track= %d에서 읽을 수 없습니다.
섹터 =%d\n",헤드,트랙,섹터);
}
}
}
}
fclose(tt);
}
이 예에서는 biosdisk 및 _bios_disk 함수의 사용을 보여줍니다. biosdisk 함수는 디스크가 준비되었는지 확인하고 주소 표시가 발견되었는지 확인합니다. _bios_disk 함수는 최대 4개 트랙까지 양쪽의 섹터를 읽습니다.
디스크 표면에서의 읽기(또는 쓰기) 순서는 다음과 같습니다.
absread 및 abswrite 함수
이러한 함수는 Dos.h 에 정의되어 있습니다 . absread 함수는 절대 디스크 섹터를 읽고 abswrite 함수는 절대 디스크 섹터를 씁니다. absread 함수는 DOS 인터럽트 0x25를 사용하여 특정 디스크 섹터를 읽고 abswrite 함수는 DOS 인터럽트 0x26을 사용하여 특정 디스크 섹터를 씁니다.
절대 읽기 또는 쓰기 작업은 섹터를 단계적으로 증가시키는 순차적 방식으로 진행되며 헤드 및 트랙 번호 등과 전혀 관련이 없습니다. 절대 섹터를 해당 트랙, 헤드 및 섹터 번호로 변환하는 것은 컴퓨터의 BIOS의 역할입니다.
디스크 전체에 대한 읽기/쓰기 작업을 수행하며, 프로그램 속도를 최대한 높이기 위해 프로그램에서 추가적인 코딩과 루핑을 피하려는 경우에는 절대 읽기 및 쓰기 작업이 권장됩니다.
absread와 abswrite 함수는 모두 디스크의 논리적 구조를 무시하고 파일, FAT 또는 디렉토리에 주의를 기울이지 않습니다. 이러한 함수는 디스크 표면에서 절대 읽기 및 절대 쓰기 작업을 직접 수행합니다. 이것이 abswrite가 부적절하게 사용되면 파일, 디렉토리 및 FAT를 덮어쓸 수 있는 이유입니다.
absread 함수의 선언은 다음과 같습니다.
int absread(int 드라이브, int nsects, long lsect,
void *버퍼);
그리고 abswrite 함수는 다음과 같이 선언됩니다.
int 드라이브, int nsects, long lsect,
void *버퍼);
매개변수의 의미는 다음과 같습니다.
매개변수 |
그것이 무엇인가/무엇을 하는가 |
운전하다 |
읽을(또는 쓸) 드라이브 번호: 0 = A, 1 = B 등. |
곤충 |
읽을(또는 쓸) 섹터 수 |
섹션 |
시작 논리 섹터 번호 |
완충기 |
데이터를 읽을(또는 쓸) 메모리 주소 |
성공 시 두 함수 모두 0을 반환합니다. 오류가 발생하면 두 함수 모두 -1을 반환하고 오류 번호를 시스템 호출에서 반환한 AX 레지스터 값으로 설정합니다.
읽기 또는 쓰기 작업을 위한 섹터 수는 64K 또는 버퍼 크기 중 더 작은 크기로 제한됩니다. 그러나 다음 장에서 거대한 메모리를 사용하여 메모리 제한인 64K를 초과하여 매우 빠른 프로그램을 개발하는 방법을 배우게 됩니다.
|
C를 사용한 인터럽트 처리
C는 정의된 일부 함수를 사용하여 다양한 인터럽트를 호출할 수 있기 때문에 때때로 고급 어셈블리 언어라고 불립니다. 몇 가지 중요한 함수는 다음과 같습니다.
- int86: MS-DOS 인터럽트를 호출합니다.
- int86x: 세그먼트 레지스터 값을 사용하여 MS-DOS 인터럽트를 호출합니다.
- intdos: DX 및 AL 이외의 레지스터를 사용하여 MS-DOS 서비스를 호출합니다.
- intdosx: 세그먼트 레지스터 값을 사용하여 MS-DOS 서비스를 호출합니다.
- segread: 세그먼트 레지스터 읽기
우리는 이러한 함수에 대해 자세히 논의할 것입니다. 우선, 우리는 이러한 함수와 함께 자주 또는 반드시 사용되는 일부 미리 정의된 구조와 유니온에 대해 논의합니다.
SREGS 구조
이 구조는 dos.h에 정의되어 있으며, int86x, intdosx 및 segread 함수에 전달되고 채워진 세그먼트 레지스터의 구조입니다. 구조의 선언은 다음과 같습니다.
구조체 SREGS {
부호 없는 정수;
부호 없는 int cs;
부호 없는 int ss;
부호 없는 int ds;
};
REGS 연합
REGS는 두 구조의 합집합입니다. 합집합 REGS는 dos.h에 정의되어 있으며, int86, int86x, intdos 및 intdosx 함수 간에 정보를 주고받는 데 사용됩니다. 합집합의 선언은 다음과 같습니다.
유니온 REGS {
구조체 WORDREGS x;
구조체 BYTEREGS h;
};
BYTEREGS 및 WORDREGS 구조
BYTEREGES 및 WORDREGS 구조는 dos.h에 정의되어 있으며, 이는 바이트 및 워드 레지스터를 저장하는 데 사용됩니다. WORGREGS 구조를 사용하면 사용자가 CPU의 레지스터에 16비트 수량으로 액세스할 수 있는 반면 BYTEREGES 구조는 개별 8비트 레지스터에 대한 액세스를 제공합니다.
BITEREGS 구조는 다음과 같이 선언됩니다.
구조체 BYTEREGS {
서명 없는 char al, ah, bl, bh;
부호 없는 char cl, ch, dl, dh;
};
그리고 WORDREGS 구조체는 다음과 같이 선언됩니다.
구조체 WORDREGS {
부호 없는 int ax, bx, cx, dx;
unsigned int 예, 의, cflag, 플래그;
};
int86 및 int86x 함수
이러한 함수는 dos.h에 정의된 일반 8086 소프트웨어 인터럽트 인터페이스입니다. 레지스터는 원하는 값으로 설정되고 이러한 함수는 MS-DOS 인터럽트를 호출하기 위해 호출됩니다. int86 함수의 선언은 다음과 같습니다.
int int86(int intno, union REGS *inregs,
union REGS *outregs);
int86x는 int86 함수의 변형입니다. 다음과 같이 선언됩니다.
int int86x(int intno, union REGS *inregs,
union REGS *outregs, struct SREGS *segregs);
int86과 int86x 함수는 모두 인수 intno에 의해 지정된 8086 소프트웨어 인터럽트를 실행합니다. 혹은 생성할 인터럽트가 intno에 의해 지정되었다고 할 수도 있습니다.
int86x 함수를 사용하면 ES와 DS에만 액세스할 수 있고 CS와 SS에는 액세스할 수 없으므로 기본 데이터 세그먼트와 다른 DS 값을 사용하거나 ES에서 인수를 받는 8086 소프트웨어 인터럽트를 호출할 수 있습니다.
이러한 기능은 소프트웨어 인터럽트를 실행하기 전에 inregs에서 레지스터 값을 레지스터로 복사합니다. int86x 함수는 소프트웨어 인터럽트를 실행하기 전에 segregs->ds 및 segregs->es 값을 해당 레지스터로 복사합니다. 이 기능을 사용하면 far 포인터나 대용량 데이터 메모리 모델을 사용하는 프로그램이 소프트웨어 인터럽트에 사용할 세그먼트를 지정할 수 있습니다.
이 함수는 소프트웨어 인터럽트가 반환된 후 현재 레지스터 값을 outregs에 복사하고, 캐리 플래그 상태를 outregs의 x.cflag 필드에 복사하고, 8086 플래그 레지스터 값을 outregs의 x.flags 필드에 복사합니다. int86x 함수는 또한 DS를 복원하고 segregs->es 및 segregs->ds 필드를 해당 세그먼트 레지스터의 값으로 설정합니다.
두 함수 모두 inregs와 outregs는 동일한 구조를 가리킬 수 있으며 두 함수 모두 소프트웨어 인터럽트가 완료된 후 AX의 값을 반환합니다. 캐리 플래그가 설정된 경우 일반적으로 오류가 발생했음을 나타냅니다.
C에서 사용되는 REGS 유니온 요소는 어셈블리 언어와 동일하게 다음 표에 나와 있습니다.
16비트 |
8비트 |
C언어 |
어셈블리 언어 |
C언어 |
어셈블리 언어 |
등록.x.ax |
도끼 |
등록.h.al |
알 |
|
|
인레그스.h.ah |
아 |
등록.x.bx |
비엑스 |
인레그스.h.bl |
비엘 |
|
|
등록.h.bh |
비에이치 |
등록.x.cx |
고객 서비스 |
inregs.h.cl |
씨엘 |
|
|
inregs.h.ch |
체 |
등록.x.dx |
디엑스 |
인레그스.h.dl |
디엘에이 |
|
|
등록.h.dh |
남편 |
등록.x.si |
그리고 |
|
|
inregs.x.of |
에서 |
|
|
inregs.x.cflag |
CF |
|
|
int86 및 int86x 함수의 예를 살펴보겠습니다. 다음 프로그램은 플로피 디스크의 모든 섹터를 스캔하고 모든 섹터의 상태를 화면에 인쇄합니다.
/* 플로피 디스크의 모든 섹터를 스캔하고 상태를 인쇄하는 프로그램 */
#include<dos.h>
#include<conio.h>
void 메인()
{
int 헤드,트랙,섹터,i;
char *버프;
노동조합 REGS inregs, outregs;
구조체 SREGS sregs;
영어: clrscr();
/// 디스크 시스템을 재설정하여 디스크를 초기화합니다 \\\
gotoxy(10,2); printf("디스크 초기화 중...");
i=0;i<3;i++에 대하여
{
inregs.h.ah=0x00; // 함수 번호
inregs.h.dl=0x00; // 플로피 디스크
int86(0x13,&입력 레지스터,&출력 레지스터);
}
gotoxy(10,2); printf("디스크의 상태는...\n");
/* 플로피 디스크를 0~79개 트랙까지 스캔(총 트랙 80개) */
트랙=0;트랙<=79;트랙++)
for(머리=0;머리<=1;머리++)
섹터=1;섹터<=18;섹터++)
{
inregs.h.ah = 0x04; /// 함수 번호
inregs.h.al = 1; /// 섹터 수
inregs.h.dl = 0x00; /// 플로피 디스크
inregs.h.ch = 트랙;
inregs.h.dh = 헤드;
inregs.h.cl = 섹터;
inregs.x.bx = FP_OFF(버프);
sregs.es = FP_SEG(버프);
int86x(0x13,&입력 레지스터,&출력 레지스터,&s레그);
//// 스캔된 섹터의 상태 인쇄 \\\\
스위치(outregs.h.ah)
{
케이스 0x00:
cprintf("상태: 오류 없음 !!");
부서지다;
케이스 0x01:
cprintf("상태: 잘못된 명령 ");
부서지다;
케이스 0x02:
cprintf("상태: 주소 표시를 찾을 수 없습니다 ");
부서지다;
케이스 0x03:
cprintf("상태: 쓰기 시도 중
쓰기 보호된 디스크 ");
부서지다;
케이스 0x04:
cprintf("상태: 섹터를 찾을 수 없습니다 ");
부서지다;
케이스 0x05:
cprintf("상태: 재설정 실패(하드 디스크) ");
부서지다;
케이스 0x06:
cprintf("상태: 디스크가 마지막 이후로 변경되었습니다.
작업 ");
부서지다;
케이스 0x07:
cprintf("상태: 드라이브 매개변수 활동
실패했습니다") ;
부서지다;
케이스 0x08:
cprintf("상태: 직접 메모리 액세스(DMA)
오버런 ");
부서지다;
케이스 0x09:
cprintf("상태: DMA를 수행하려고 시도합니다.
64K 경계 ");
부서지다;
케이스 0x0A:
cprintf("상태: 불량 섹터가 감지되었습니다 ");
부서지다;
케이스 0x0B:
cprintf("상태: 잘못된 트랙이 감지되었습니다 ");
부서지다;
케이스 0x0C:
cprintf("상태: 미디어 유형을 찾을 수 없습니다 ");
부서지다;
케이스 0x0D:
cprintf("상태: 섹터 수가 잘못되었습니다.
포맷(하드디스크) ");
부서지다;
케이스 0x0E:
cprintf("STATUS: 제어 데이터 주소 표시
(하드디스크)가 감지되었습니다 .
부서지다;
케이스 0x0F:
cprintf("상태: DMA 중재 수준이 벗어났습니다.
범위(하드디스크) ");
부서지다;
케이스 0x10:
cprintf("상태: 디스크 읽기의 CRC/ECC가 잘못되었습니다 ");
부서지다;
케이스 0x11:
cprintf("상태: CRC/ECC 수정된 데이터 오류 ");
부서지다;
케이스 0x20:
cprintf("상태: 컨트롤러가 실패했습니다 ");
부서지다;
케이스 0x31:
cprintf("상태: 드라이브에 미디어가 없습니다(IBM/MS INT 13H
확장자) ");
부서지다;
케이스 0x32:
cprintf("상태: 잘못된 드라이브 유형이 저장되었습니다.
CMOS(컴팩) ");
부서지다;
케이스 0x40:
cprintf("상태: 검색 작업이 실패했습니다 ");
부서지다;
케이스 0x80:
cprintf("상태: 첨부 파일이 응답하지 않았습니다.
(디스크 시간 초과) ");
부서지다;
케이스 0xAA:
cprintf("상태: 드라이브가 준비되지 않았습니다(하드 디스크
오직) ");
부서지다;
케이스 0xB0:
cprintf("상태: 볼륨이 드라이브에 잠겨 있지 않음(INT)
13H 확장) ");
부서지다;
케이스 0xB1:
cprintf("상태: 드라이브의 볼륨이 잠겼습니다(INT 13H 확장자) ");
부서지다;
케이스 0xB2:
cprintf("상태: 볼륨을 제거할 수 없습니다(INT 13H
확장자) ");
부서지다;
케이스 0xB3:
cprintf("상태: 볼륨 사용 중(INT 13H
확장자) ");
부서지다;
케이스 0xB4:
cprintf("상태: 잠금 횟수가 초과되었습니다(INT 13H
확장자) ");
부서지다;
케이스 0xB5:
cprintf("상태: 유효한 꺼내기 요청이 실패했습니다(INT
13H 확장) ");
부서지다;
케이스 0xBB:
cprintf("상태: 정의되지 않은 오류가 발생했습니다(하드
디스크만 해당) ");
부서지다;
케이스 0xCC:
cprintf("상태: 쓰기 오류가 발생했습니다 ");
부서지다;
케이스 0xE0:
cprintf("상태: 상태 레지스터 오류 ");
부서지다;
케이스 0xFF:
cprintf("상태: 감지 작업이 실패했습니다 ");
부서지다;
기본값: cprintf("상태: 알 수 없는 상태 코드 ");
}
printf("\n현재 위치= 트랙:%d 헤드:%d 섹터:%d \n",
트랙, 헤드, 섹터);
}
gotoxy(10,24);printf("스캐닝이 완료되었습니다!! 아무 키나 누르세요
출구..");
getch();
}
이 프로그램은 int86 및 int86x 함수 사용 예를 보여줍니다. 이 프로그램에서 int86 함수는 INT 13H의 함수 00H를 사용하여 디스크 시스템을 재설정하여 디스크를 초기화합니다. int86x 함수는 INT 13H의 함수 04H를 사용하여 양쪽에서 플로피 디스크(1.44Mb, 3½ 플로피 디스크)의 모든 섹터를 최대 0~79개 트랙(총 80개 트랙)까지 확인합니다.
segread 함수
이 함수는 dos.h에서 정의되었습니다. 이 함수는 세그먼트 레지스터를 읽습니다. 함수의 선언은 다음과 같습니다.
void segread(구조체 SREGS *segp);
여기서 segread는 세그먼트 레지스터의 현재 값을 구조 *segp에 넣습니다. 함수에서 반환되는 것은 없으며 호출은 intdosx 및 int86x와 함께 사용하도록 의도되었습니다. 예를 들어 보겠습니다.
#include <stdio.h>
#include <dos.h>
void 메인()
{
구조체 SREGS 세그먼트;
세그레드(&segs);
printf("현재 세그먼트 레지스터 설정\n\n");
printf("CS: %X DS: %X\n", segs.cs, segs.ds);
printf("ES: %X SS: %X\n", segs.es, segs.ss);
getch();
}
그리고 프로그램의 출력은 다음과 같습니다.
현재 세그먼트 레지스터 설정
CS: EED DS: 10BA
ES: 10BA SS: 10BA
intdos 및 intdosx 함수
이러한 함수는 dos.h에 정의되어 있습니다. 이들은 일반적인 DOS 인터럽트 인터페이스입니다. 함수 intdos는 MS-DOS 서비스 레지스터를 호출한 다음 DX와 AL을 호출하고 함수 intdosx는 세그먼트 레지스터 값으로 MS-DOS 서비스를 호출합니다.
intdos 함수의 선언은 다음과 같습니다.
int intdos(union REGS *inregs, union REGS *outregs);
그리고 intdosx 함수의 선언은 다음과 같습니다:
int intdosx(union REGS *inregs, union REGS *outregs,
구조체 SREGS *segregs);
함수 intdos 와 intdosx는 DOS 인터럽트 0x21을 실행하여 지정된 DOS 함수를 호출합니다. inregs->h.ah의 값은 호출할 DOS 함수를 지정합니다. 함수 intdosx는 또한 DOS 함수를 호출하기 전에 segregs ->ds 및 segregs ->es 값을 해당 레지스터에 복사한 다음 DS를 복원합니다.
이 함수의 특징은 far 포인터나 대용량 데이터 메모리 모델을 사용하는 프로그램이 함수 실행에 사용할 세그먼트를 지정할 수 있게 해줍니다. intdosx 함수를 사용하면 기본 데이터 세그먼트와 다른 DS 값을 사용하거나 ES에서 인수를 사용하는 DOS 함수를 호출할 수 있습니다.
두 함수 모두 DOS 함수 호출이 완료된 후 AX의 값을 반환하고, 캐리 플래그가 설정된 경우(outregs -> x.cflag != 0) 오류가 발생했음을 나타냅니다.
인터럽트 0x21이 반환된 후 함수는 현재 레지스터 값을 outregs에 복사하고, 캐리 플래그 상태를 outregs의 x.cflag 필드에 복사하고, 8086 플래그 레지스터 값을 outregs의 x.flags 필드에 복사합니다. inregs와 outregs는 모두 동일한 구조를 가리킬 수 있습니다. 이러한 함수의 예를 살펴보겠습니다.
intdos 함수 사용의 예가 아래에 나와 있습니다. 이 프로그램은 플로피(1.44Mb, 3½ 인치 플로피 디스크) 디스크 드라이브에 대한 선택된 정보를 얻습니다. 이 프로그램은 플로피 디스크의 할당 정보를 제공합니다.
/* 디스크 사용에 대한 드라이브 할당 정보 가져오기 */
#include <dos.h> /* intdos() 및 union REGS의 경우 */
#include <stdio.h> /* printf()용 */
노동조합 REGS inregs, outregs;
void 메인()
{
inregs.h.ah = 0x36; /* 디스크 여유 공간 얻기
함수 번호 */
inregs.h.dl = 0x01; /* 드라이브 A: */
intdos(&inregs, &outregs);
printf("%d 섹터/클러스터,\n%d 클러스터,\n%d 바이트/섹터,
\n총 클러스터 수 %d",
아웃레그.x.ax, 아웃레그.x.bx,
아웃레그.x.cx, 아웃레그.x.dx);
getch();
}
그리고 프로그램의 출력은 다음과 같습니다:
1 섹터/클러스터,
1933 클러스터,
512바이트/섹터,
총 클러스터 2843개
이제 intdosx 함수 의 예를 살펴보겠습니다 . 다음 예는 intdosx 함수 의 사용을 보여줍니다 . 프로그램은 표준 출력에 문자열을 출력합니다.
/* '문자열'을 표준 출력에 출력하는 프로그램. */
#include <dos.h>
노동조합 REGS inregs, outregs;
구조체 SREGS 분리;
char far *string = "이 문자열은
기본 데이터 세그먼트$";
void 메인()
{
inregs.h.ah = 0x09; /* 함수 번호 */
inregs.x.dx = FP_OFF(string);/*DS:DX는 멀리 있습니다
'문자열 */의 주소
segregs.ds = FP_SEG(문자열);
intdosx(&inregs, &outregs, &segregs);
getch();
}
그리고 프로그램의 출력은 다음과 같습니다.
이 문자열은 기본 데이터 세그먼트에 없습니다. |
여기서 우리는 INT 21H의 함수 09H를 통해 intdosx 함수로 주어진 문자열을 인쇄하고 있습니다 . 주어진 문자열은 항상 문자 "$"로 끝나야 한다는 것을 항상 명심해야 합니다.
실제 하드 드라이브 번호를 아는 방법
실제 하드 드라이브 번호는 매우 중요한 사항이며 정확하게 작성해야 합니다. 불법 드라이브 사양은 주요 데이터 손실을 초래할 수 있습니다. 데이터 복구 또는 디스크 문제 해결 프로그래밍 중에 드라이브 번호에 대해 확신해야 합니다. 디스크 배열이 다른 모든 디스크의 드라이브 번호를 아는 방법은 다음에 제공된 예를 통해 추정할 수 있습니다.
가장 일반적인 신화에 따르면, 물리적 드라이브 번호는 디스크의 연결 상태에 따라 제공되지만 일부 또는 특수한 경우에는 운영 체제의 부팅 절차나 부팅 설정에 따라 달라질 수 있습니다.
BIOS에서 제공하는 물리적 드라이브 번호 에 대한 가장 일반적인 아이디어는 여기에 제공되었지만, 그때도 디스크 편집 도구나 다음 장에서 제공하는 프로그램을 사용하여 디스크 구성에 대해 확인해야 합니다. 불법적으로 또는 지식이 부족하여 사용하는 경우 데이터를 손상시키거나 손상시킬 수 있는 이러한 프로그램을 실행하는 것에 대한 결정을 내려야 합니다.
일반적으로 두 개의 디스크가 시스템에 연결되어 있고, 하나는 기본 마스터이고 다른 하나는 보조 마스터인 경우, 기본 마스터에 가장 큰 우선권이 주어지고(그리고 사용 가능한 경우 기본 슬레이브에 주어짐) 그다음 보조 마스터에 주어지고(그리고 사용 가능한 경우 보조 슬레이브에 주어짐) 선호도에 따라 물리적 개수가 지정됩니다.
시스템이 한 번에 최대 4개의 하드 디스크를 지원한다고 가정해 보겠습니다. 4개의 하드 디스크는 모두 주어진 대로 연결될 수 있습니다. 다음:
초등학교 마스터 |
1차 슬레이브 |
중등 석사 |
2차 슬레이브 |
이제 실제 드라이브의 드라이브 번호에 대한 몇 가지 사례를 고려해 보겠습니다. 여기서는 디스크 제조업체에서 언급한 대로 적절한 점퍼 설정과 적절한 마스터-슬레이브 설정으로 디스크를 연결했다고 가정합니다.
- 4개의 하드 디스크가 모두 시스템에 연결된 경우: 4개의 디스크가 모두 시스템에 연결된 경우 물리적 드라이브 번호는 다음과 같습니다.
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
1차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
중등 석사 |
디스크가 존재합니다 |
물리적 드라이브 번호는 82H입니다 . 이 경우 하드 디스크는 세 번째 하드 디스크 라고 합니다 . |
2차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 83H입니다 . 이 경우 하드 디스크는 네 번째 하드 디스크 라고 합니다 . |
- 세 개의 하드 디스크가 시스템에 연결된 경우: 세 개의 하드 디스크가 시스템에 연결된 경우 물리적 드라이브 번호는 연결 선호도에 따라 달라집니다. 다음 예는 일부 배열을 나타냅니다.
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
1차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
중등 석사 |
디스크가 존재합니다 |
물리적 드라이브 번호는 82H입니다 . 이 경우 하드 디스크는 세 번째 하드 디스크 라고 합니다 . |
2차 슬레이브 |
디스크가 없습니다 |
------------------- |
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 없습니다 |
------------------- |
1차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
중등 석사 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
2차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 82H입니다 . 이 경우 하드 디스크는 세 번째 하드 디스크 라고 합니다 . |
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
1차 슬레이브 |
디스크가 없습니다 |
------------------- |
중등 석사 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
2차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 82H입니다 . 이 경우 하드 디스크는 세 번째 하드 디스크 라고 합니다 . |
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
1차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
중등 석사 |
디스크가 없습니다 |
------------------- |
2차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 82H입니다 . 이 경우 하드 디스크는 세 번째 하드 디스크 라고 합니다 . |
- 두 개의 하드 디스크가 시스템에 연결된 경우: 마찬가지로 두 개의 하드 디스크가 시스템에 연결된 경우 물리적 드라이브 번호는 연결 선호도에 따라 달라집니다. 다음 예는 이를 보여줍니다.
1차/2차(마스터/슬레이브) |
상태 |
물리적 드라이브 번호 및 설명 |
초등학교 마스터 |
디스크가 존재합니다 |
물리적 드라이브 번호는 80H입니다 . 이 경우 하드 디스크를 첫 번째 하드 디스크 라고 합니다 . |
1차 슬레이브 |
디스크가 없습니다 |
------------------- |
중등 석사 |
디스크가 없습니다 |
------------------- |
2차 슬레이브 |
디스크가 존재합니다 |
물리적 드라이브 번호는 81H입니다 . 이 경우 하드 디스크는 두 번째 하드 디스크 라고 합니다 . |
- 시스템에 단일 하드 디스크가 연결된 경우: 생각할 필요 없습니다. 사용 가능한 디스크가 하나뿐이라면 물리적 드라이브 번호는 80H가 됩니다.
인터럽트 13H(INT 13H), ROM BIOS 디스크 드라이버 기능
INT 13H 함수에 대한 설명이 여기에 나와 있습니다. 이러한 함수는 주의해서 배워야 합니다. 이러한 함수를 잘못 사용하거나 부주의하거나 지식이 부족한 상태에서 사용하면 많은 데이터 손실이나 다른 많은 문제가 발생할 수 있습니다. 그러나 적절하고 적절한 방식으로 사용하면 이러한 함수는 프로그램 코딩을 최소화하고 프로그래밍을 간단하고 쉽게 만드는 데 도움이 됩니다.
INT 13H (0x13)
기능 00H (0x00) 디스크 시스템 재설정
AH = 00H 로 호출
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
반환값: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
디스크 컨트롤러를 재설정하고, 연결된 드라이브를 재보정합니다. 읽기/쓰기 암을 실린더 0으로 옮기고 디스크 I/O를 준비합니다.
이 기능은 플로피 디스크 읽기, 쓰기, 확인 또는 포맷 요청이 실패한 후에 호출되어야 하며, 작업을 다시 시도하기 전에 호출되어야 합니다. 고정 디스크 드라이브(예: DL>=80H 선택)로 함수를 호출하면 플로피 디스크 컨트롤러와 고정 디스크 컨트롤러가 재설정됩니다.
INT 13H (0x13)
기능 01H (0x01) 디스크 시스템 상태 가져오기
AH = 01H 로 전화하세요
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
반환: AH = 00H
AL = 이전 디스크 작업 상태
(오류에 대해서는 이전에 제공된 표를 참조하세요.
및 상태 코드 설명).
댓글:
가장 최근의 디스크 작업 상태를 반환합니다.
INT 13H (0x13)
기능 02H (0x02) 섹터 읽기
AH = 02H 로 전화하세요
AL = 섹터 수
CH = 실린더
CL = 섹터
DH = 머리
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
ES:BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
AL = 전송된 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 디스크에서 하나 이상의 섹터를 메모리로 읽습니다. 고정 디스크에서는 10비트 실린더 번호의 상위 2비트가 레지스터 CL의 상위 2비트에 배치됩니다.
INT 13H (0x13)
기능 03H (0x03) 섹터 쓰기
AH = 03H 로 전화하세요
AL = 섹터 수
CH = 실린더
CL = 섹터
DH = 머리
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
ES: BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
AL = 전송된 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 메모리에서 디스크로 하나 이상의 섹터를 씁니다. 고정 디스크에서 10비트 실린더 번호의 상위 2비트는 레지스터 CL의 상위 2비트에 배치됩니다.
INT 13H (0x13)
기능 04H (0x04) >> 섹터 확인
AH = 04H 로 전화하세요
AL = 섹터 수
CH = 실린더
CL = 섹터
DH = 운전
00H-7FH 플로피 디스크
80H-FFH 고정구동
ES: BX = 세그먼트: 버퍼의 오프셋
반환값: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
AL = 검증된 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 기능은 하나 이상의 섹터의 주소 필드를 검증합니다. 이 작업으로 인해 메모리에서 데이터가 전송되거나 메모리로 데이터가 전송되지 않습니다. 고정 디스크에서 10비트 실린더 번호의 상위 2비트는 레지스터 CL의 상위 2비트에 다시 배치됩니다.
이 기능은 플로피 디스크 드라이브에 읽을 수 있는 미디어가 있는지 테스트하는 데 사용할 수 있습니다. 요청하는 프로그램은 플로피 디스크 시스템을 재설정(INT 13H 기능 00H)하고 읽을 수 있는 플로피 디스크가 없다고 가정하기 전에 작업을 세 번 다시 시도해야 합니다. 대부분의 플로피 초기화 작업에서 권장됩니다.
INT 13H (0x13)
기능 05H (0x05) >> 트랙 포맷
AH = 05H 로 전화하세요
AL = 인터리브(PC/XT 고정 디스크)
CH = 실린더
DH = 머리
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
ES: BX = 세그먼트: 주소 필드 목록의 오프셋
(PC/XT 고정디스크 제외)
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태(제공된 상태 표 참조)
더 일찍)
설명:
지정된 트랙에서 디스크 섹터와 트랙 주소 필드를 초기화합니다. 플로피 디스크에서 주소 필드 목록은 섹터당 하나의 항목인 일련의 4바이트 항목으로 구성됩니다. 형식은 다음 표에 나와 있습니다.
고정 디스크에서는 10비트 실린더 번호의 상위 2비트가 CL 레지스터의 상위 2비트에 배치됩니다.
바이트 |
내용물 |
0 |
실린더 |
1 |
머리 |
2 |
부문 |
3
|
섹터 크기 코드
값 |
설명 |
00시 |
섹터당 128바이트 |
01시 |
섹터당 256바이트 |
02시 |
섹터당 512바이트 |
03시 |
섹터당 1024바이트 |
|
INT 13H (0x13)
기능 06H(0x06) >> 잘못된 트랙 포맷
AH = 06H 로 전화하세요
AL = 인터리브
CH = 실린더
DH = 머리
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 PC/XT 고정 디스크 드라이브에만 정의되어 있습니다. 트랙을 초기화하고 디스크 주소 필드와 데이터 섹터를 쓰고 불량 섹터 플래그를 설정합니다.
INT 13H (0x13)
기능 07H (0x07) >> 드라이브 포맷
AH = 07H 로 전화하세요
AL = 인터리브
CH = 실린더
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태(제공된 상태 표 참조)
더 일찍)
설명:
이 기능은 PC/XT 고정 디스크 드라이브에만 정의되어 있습니다. 지정된 실린더에서 시작하여 디스크 주소 필드와 데이터 섹터를 쓰면서 전체 드라이브를 포맷합니다.
INT 13H (0x13)
기능 08H (0x08) >> 드라이브 매개변수 가져오기
AH = 08H 로 전화하세요
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
BL = 드라이브 유형(PC/AT 및 PS/2 플로피)
디스크)
값 |
설명 |
01시 |
360KB, 40트랙, 5.25인치 |
02시 |
1.2MB, 80트랙, 5.25인치 |
03시 |
720KB, 80트랙, 3.5인치 |
04시 |
1.44MB, 80트랙, 3.5인치 |
CH = 최대 실린더의 하위 8비트
숫자
CL = 비트 6-7 상위 2비트 최대
실린더 번호 비트 0-5 최대
섹터 번호
DH = 최대 헤드 수
DL = 드라이브 수
ES: DI = 세그먼트: 디스크 드라이브의 오프셋
매개변수 테이블
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 함수는 지정된 드라이브에 대한 다양한 매개변수를 반환합니다. 레지스터 DL에 반환된 값은 요청된 드라이브에 대한 어댑터에 연결된 실제 드라이브의 실제 수를 반영합니다.
INT 13H (0x13)
함수 09H (0x09) >> 고정 디스크 특성 초기화
AH = 09H 로 전화하세요
DL = 드라이브
80H-FFH 고정디스크
INT 41H를 위한 PC/XT 벡터에서
디스크 매개변수 블록을 가리켜야 하거나 PC/AT 및 PS/2에서
INT 41H의 벡터는 디스크를 가리켜야 합니다.
드라이브 0에 대한 매개변수 블록
INT 46H의 벡터는 디스크를 가리켜야 합니다.
드라이브 1의 매개변수 블록
반환값 : 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 ROM BIOS 디스크 매개변수 블록에서 찾은 값을 사용하여 후속 I/O 작업을 위해 고정 디스크 컨트롤러를 초기화합니다. 이 기능은 고정 디스크에서만 지원됩니다. PC 및 PC/XT 고정 디스크의 매개변수 블록 형식은 다음과 같습니다.
변경(들) |
내용물 |
00시-01시 |
최대 실린더 수 |
02시 |
최대 헤드 수 |
03시~04시 |
감소된 쓰기 전류 실린더 시작 |
05시~06시 |
쓰기 전 보상 실린더 시작 |
07시 |
최대 ECC 버스트 길이 |
08시
|
드라이브 옵션
비트(들) |
중요성(설정된 경우) |
0 – 2 |
드라이브 옵션 |
3 – 5 |
예약됨 (0) |
6 |
ECC 항목 비활성화 |
7 |
디스크 액세스 재시도 비활성화 |
|
09시 |
표준 타임아웃 값 |
0아 |
포맷 드라이브의 시간 초과 값 |
0비에이치 |
드라이브 검사에 대한 시간 초과 값 |
0CH-0FH |
예약된 |
PC/AT 및 PS/2 고정 디스크의 매개변수 블록 형식은 다음과 같습니다.
변경(들) |
내용물 |
00H_01H |
최대 실린더 수 |
02시 |
최대 헤드 수 |
03시~04시 |
예약된 |
05시~06시 |
쓰기 시작 사전 보상 실린더 |
07시 |
최대 ECC 버스트 길이 |
08시 |
드라이브 옵션
비트(들) |
중요성(설정된 경우) |
0 – 2 |
사용하지 않음 |
3 |
8개 이상의 머리 |
4 |
사용하지 않음 |
5 |
최대 실린더 +1 에 제조업체 결함 맵이 존재합니다 . |
6 – 8 |
재시도가 비활성화된 경우 0이 아닌 값(10, 01 또는 11) |
|
09H-0BH |
예약된 |
0CH-0DH |
랜딩 존 실린더 |
0EH |
트랙당 섹터 |
0FH |
예약된 |
INT 13H (0x13)
기능 0A H (0x0A 또는 10) >> 섹터 길이 읽기
AH = 0AH 로 호출
AL = 섹터 수
CH = 실린더
CL = 섹터
DH = 머리
DL = 드라이브
80H-FFH 고정디스크
ES: BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
AL = 전송된 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 기능은 디스크에서 섹터 하나 이상을 메모리로 읽어들이고 각 섹터에 대한 4바이트 오류 정정 코드(ECC) 코드를 함께 읽습니다. 일반적인 Read sector 기능(INT 13H (0x13) Function 02H)과 달리 ECC 오류는 자동으로 정정되지 않습니다. 다중 섹터 전송은 읽기 오류가 있는 섹터가 발생하면 종료됩니다.
이 기능은 고정 디스크에서만 지원됩니다. 10비트 실린더 번호의 상위 2비트는 레지스터 CL의 상위 2비트에 배치됩니다.
INT 13H (0x13)
함수 0BH (0x0B 또는 11) >> 섹터 길이 쓰기
AH = 0BH 로 호출
AL = 섹터 수
CH = 실린더
CL = 섹터
DH = 머리
DL = 드라이브
80H-FFH 고정디스크
ES: BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
AL = 전송된 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 메모리에서 디스크로 섹터를 씁니다. 각 섹터의 데이터 가치 뒤에 4바이트 ECC 코드가 와야 합니다. 10비트 실린더 번호의 상위 2비트는 레지스터 CL의 상위 2비트에 배치됩니다. 이 기능은 고정 디스크에서만 지원됩니다.
INT 13H (0x13)
기능 0CH (0x0C 또는 12) >> 탐색
AH = 0CH 로 호출
CH = 실린더의 하위 8비트
CL = 비트 6-7의 실린더 상위 2비트
DH = 머리
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 데이터를 전송하지 않고 디스크 읽기/쓰기 헤드를 지정된 실린더에 배치합니다. 실린더 번호의 상위 2비트는 레지스터 CL의 상위 2비트에 배치됩니다. 이 기능은 고정 디스크에서만 지원됩니다.
INT 13H (0x13)
기능 0DH (0x0D 또는 13) >> 고정 디스크 시스템 재설정
AH = 0DH 로 호출
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태(INT 13H 함수 01H 참조)
댓글:
이 기능은 고정 디스크 컨트롤러를 재설정하고, 연결된 드라이브를 재보정하고, 읽기/쓰기 암을 실린더 0으로 옮기고, 후속 디스크 I/O를 준비합니다.
INT 13H (0x13)
기능 0EH (0x0E 또는 14) >> 섹터 버퍼 읽기
AH = 0EH 로 호출
ES: BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 고정 디스크 어댑터의 내부 섹터 버퍼 내용을 시스템 메모리로 전송합니다. 물리적 디스크 드라이브에서 데이터가 읽히지 않습니다.
INT 13H (0x13)
기능 0FH (0x0F 또는 15) >> 섹터 버퍼 쓰기
AH = 0FH 로 호출
ES: BX = 세그먼트: 버퍼의 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 시스템 메모리에서 고정 어댑터의 내부 섹터 버퍼로 데이터를 전송합니다. 물리적 디스크 드라이브에는 데이터가 기록되지 않습니다. 이 기능은 INT 13H Function 05H로 드라이브를 포맷하기 전에 섹터 버퍼의 내용을 초기화하기 위해 호출해야 합니다.
INT 13H (0x13)
기능 10H(0x10 또는 16) >> 드라이브 상태 가져오기
호출: AH = 10H
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 지정된 고정 디스크 드라이브가 작동하는지 테스트하고 드라이브의 상태를 반환합니다. 이 기능은 고정 디스크에서만 지원됩니다.
INT 13H (0x13)
기능 11H(0x11 또는 17) >> 드라이브 재보정
AH =11H 로 전화하세요
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 고정 디스크 어댑터가 지정된 드라이브에 대해 자체적으로 재보정하여 읽기/쓰기 암을 실린더 0에 위치시키고 드라이브의 상태를 반환합니다. 이 기능은 고정 디스크에서만 지원됩니다.
INT 13H (0x13)
기능 12H(0x12 또는 18) >> 컨트롤러 RAM 진단
호출: AH = 12H
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 고정 디스크 어댑터가 내부 섹터 버퍼에서 내장된 진단 테스트를 수행하도록 하여 반환된 상태가 테스트를 통과했는지 여부를 나타냅니다.
INT 13H (0x13)
기능 13H(0x13 또는 19) >> 컨트롤러 드라이브 진단
호출: AH = 13H
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 고정 어댑터가 연결된 드라이브의 내부 진단 테스트를 실행하여 반환된 상태에 의해 테스트에 통과했는지 여부를 나타냅니다.
INT 13H (0x13)
기능 14H(0x14 또는 20) >> 컨트롤러 내부 진단
AH = 14H 로 호출
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00H
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능을 사용하면 고정 디스크 어댑터가 내장된 진단 자체 테스트를 수행하여 반환된 상태가 테스트를 통과했는지 여부를 나타냅니다.
INT 13H (0x13)
함수 15H(0x15 또는 21) >> 디스크 유형 가져오기
AH = 15H 로 호출
DL = 드라이브
00H-7FH 플로피 디스크
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
AH = 드라이브 유형 코드
드라이브가 없는 경우 00H,
변경 라인 지원이 없는 플로피 디스크 드라이브인 경우 01H,
변경 라인 지원이 있는 플로피 디스크 드라이브인 경우
02H, 고정 디스크인 경우 03H
|
그리고 고정디스크(AH=03H)인 경우
CX: DX = 512바이트 섹터 수
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 함수는 지정된 드라이브 코드가 참조하는 플로피 또는 고정 디스크의 유형을 나타내는 코드를 반환합니다.
INT 13H (0x13)
함수 16H(0x16 또는 22) >> 디스크 변경 상태 가져오기
호출: AH = 16H
DL = 드라이브
00H-7FH 플로피 디스크
반환: 변경 라인이 비활성화되고 디스크가 변경되지 않은 경우
캐리 플래그 = 클리어
아 = 00H
변경 라인이 활성화되어 있고 디스크가 변경되었을 수 있습니다.
캐리 플래그 = 설정
아 = 06H
댓글:
이 기능은 변경 라인의 상태를 반환하여 드라이브의 디스크가 마지막 디스크 액세스 이후 교체되었는지 여부를 나타냅니다. 이 기능이 캐리 플래그가 설정된 상태로 반환되면 디스크가 반드시 변경된 것은 아니며 플로피 디스크를 제거하지 않고 디스크 드라이브 도어를 잠금 해제하고 잠그기만 하면 변경 라인을 활성화할 수 있습니다.
INT 13H (0x13)
기능 17H(0x17 또는 23) >> 디스크 유형 설정
AH = 17H 로 호출
AL = 플로피 디스크 유형 코드
값 |
설명 |
00시 |
사용하지 않음 |
01시 |
360KB 드라이브에 320/360KB 플로피 디스크 |
02시 |
1.2MB 드라이브에 320/360KB 플로피 디스크 |
03시 |
1.2MB 드라이브에 1.2MB 플로피 디스크 |
04시 |
720KB 드라이브에 720KB 플로피 디스크 |
SL = 드라이브
00H-7FH 플로피 디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00X
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
댓글:
이 기능은 지정된 드라이브에 대한 플로피 디스크 유형을 선택합니다.
내부 13H(0x13)
기능 18H(0x18 또는 24) >> 포맷에 대한 미디어 유형 설정
호출 위치: AH = 18H
CH = 실린더 수
CL = 트랙당 섹터
DL = 드라이브
00H-7FH 플로피 디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00X
ES : DI = 세그먼트 : 디스크 오프셋
미디어 유형에 대한 매개변수 표
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 기능은 지정된 드라이브에 대한 미디어 특성을 선택하므로 드라이브에 플로피 디스크가 있어야 합니다.
내부 13H(0x13)
기능 19H (0x19 또는 25) >> 주차 헤드
호출 위치: AH = 19H
DL = 드라이브
80H-FFH 고정디스크
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00X
기능이 실패하면
캐리 플래그 = 설정
AH = 상태
설명:
이 기능은 드라이브가 꺼질 때 데이터가 손상되는 것을 방지하기 위해 데이터 저장에 사용되지 않는 트랙으로 읽기/쓰기 레버를 옮깁니다.
내부 13H(0x13)
기능 1AH(0x1A 또는 26) >> ESDI 디스크 포맷
호출: AH = 1AH
AL = 상대 블록 주소(RBA)
표의 결함 수
RBA 테이블이 없으면 0
RBA 테이블이 사용되는 경우 >0
CL = 포맷 수정자 비트
페이지(들) |
중요성(설정된 경우) |
0 |
1차 결함 맵을 무시하세요 |
1 |
2차 결함 맵 무시 |
2 |
2차 결함 맵 업데이트 |
3 |
고급 표면 분석 수행 |
4 |
주기적 인터럽트 생성 |
5-7 |
예약됨(0이어야 함) |
DL = 드라이브
80H-FFH 고정디스크
ES:BX = 세그먼트:RBA 테이블 오프셋
반환: 함수가 성공한 경우
캐리 플래그 = 클리어
아 = 00X
기능이 실패하면
캐리 플래그 = 설정
AH = 상태(INT 13H 함수 01H 참조)
설명:
이 기능은 ESDI 하드 디스크 어댑터에 연결된 디스크의 디스크 섹터와 추적 주소 필드를 초기화합니다.
이 기능의 작동을 저수준 포맷이라고 하며, 섹터 수준에서 물리적 읽기/쓰기 작업을 위해 디스크를 준비합니다. 그런 다음 FDISK 명령을 사용하여 디스크를 파티션한 다음 FORMAT 명령을 사용하여 상위 레벨로 포맷하여 파일 시스템을 설치해야 합니다.