수색…


BIOS 호출

BIOS와 상호 작용하는 방법

BIOS (Basic Input / Output System)는 운영 체제가 실행되기 전에 컴퓨터를 제어합니다. BIOS에서 제공하는 서비스에 액세스하기 위해 어셈블리 코드는 인터럽트를 사용합니다. 인터럽트는

int <interrupt> ; interrupt must be a literal number, not in a register or memory

인터럽트 번호는 0과 255 사이 여야합니다 (0x00 - 0xFF).

대부분의 BIOS 호출은 AH 레지스터를 "기능 선택"매개 변수로 사용하고 AL 레지스터를 데이터 매개 변수로 사용합니다. AH 에 의해 선택된 기능은 호출 된 인터럽트에 따라 다릅니다. 일부 BIOS 호출은 AX 에서 단일 16 비트 매개 변수를 필요로하거나 매개 변수를 전혀 받아들이지 않고 단순히 인터럽트에 의해 호출됩니다. 일부는 더 많은 매개 변수를 가지고 있으며 다른 레지스터에 전달됩니다.

BIOS 호출에 사용되는 레지스터는 고정되어 있으며 다른 레지스터와 교환 할 수 없습니다.

기능 선택과 함께 BIOS 호출 사용

함수 선택 매개 변수를 사용하는 BIOS 인터럽트의 일반 구문은 다음과 같습니다.

mov ah, <function>
mov al, <data>
int <interrupt>

예제들

디스플레이에 글자를 쓰는 방법 :

mov ah, 0x0E             ; Select 'Write character' function
mov al, <char>           ; Character to write
int 0x10                 ; Video services interrupt

키보드에서 문자를 읽는 방법 (차단) :

mov ah, 0x00             ; Select 'Blocking read character' function
int 0x16                 ; Keyboard services interrupt
mov <ascii_char>, al     ; AL contains the character read
mov <scan_code>, ah      ; AH contains the BIOS scan code

외부 드라이브에서 하나 이상의 섹터를 읽는 방법 (CHS 주소 지정 사용) :

mov ah, 0x02             ; Select 'Drive read' function
mov bx, <destination>    ; Destination to write to, in ES:BX
mov al, <num_sectors>    ; Number of sectors to read at a time
mov dl, <drive_num>      ; The external drive's ID
mov cl, <start_sector>   ; The sector to start reading from
mov dh, <head>           ; The head to read from
mov ch, <cylinder>       ; The cylinder to read from
int 0x13                 ; Drive services interrupt
jc <error_handler>       ; Jump to error handler on CF set

시스템을 읽는 법 RTC (Real Time Clock) :

mov ah, 0x00             ; Select 'Read RTC' function
int 0x1A                 ; RTC services interrupt
shl ecx, 16              ; Clock ticks are split in the CX:DX pair, so shift ECX left by 16...
or cx, dx                ; and add in the low half of the pair
mov <new_day>, al        ; AL is non-zero if the last call to this function was before midnight
                         ; Now ECX holds the clock ticks (approx. 18.2/sec) since midnight
                         ; and <new_day> is non-zero if we passed midnight since the last read

RTC에서 시스템 시간을 읽는 방법 :

mov ah, 0x02             ; Select 'Read system time' function
int 0x1A                 ; RTC services interrupt
                         ; Now CH contains hour, CL minutes, DH seconds, and DL the DST flag,
                         ; all encoded in BCD (DL is zero if in standard time)
                         ; Now we can decode them into a string (we'll ignore DST for now)

mov al, ch               ; Get hour
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+0], al ; Set ten's place of hour
mov al, ch               ; Get hour again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+1], al ; Set one's place of hour

mov al, cl               ; Get minute
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+3], al ; Set ten's place of minute
mov al, cl               ; Get minute again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+4], al ; Set one's place of minute

mov al, dh               ; Get second
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+6], al ; Set ten's place of second
mov al, dh               ; Get second again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+7], al ; Set one's place of second
...
db CLOCK_STRING "00:00:00", 0   ; Place in some separate (non-code) area

RTC에서 시스템 날짜를 읽는 방법 :

mov ah, 0x04             ; Select 'Read system date' function
int 0x1A                 ; RTC services interrupt
                         ; Now CH contains century, CL year, DH month, and DL day, all in BCD
                         ; Decoding to a string is similar to the RTC Time example above

인접한 저 메모리의 크기를 얻는 방법 :

int 0x12                 ; Conventional memory interrupt (no function select parameter)
and eax, 0xFFFF          ; AX contains kilobytes of conventional memory; clear high bits of EAX
shl eax, 10              ; Multiply by 1 kilobyte (1024 bytes = 2^10 bytes)
                         ; EAX contains the number of bytes available from address 0000:0000

컴퓨터를 재부팅하는 방법 :

int 0x19                 ; That's it! One call. Just make sure nothing has overwritten the
                         ; interrupt vector table, since this call does NOT restore them to the
                         ; default values of normal power-up. This means this call will not
                         ; work too well in an environment with an operating system loaded.

오류 처리

일부 BIOS 호출은 모든 시스템에서 구현되지 않을 수 있으며 작동하지 않을 수도 있습니다. 종종 구현되지 않은 인터럽트는 레지스터 AH 에서 0x86 또는 0x80 을 반환합니다. 거의 모든 인터럽트는 오류 상태에서 캐리 플래그 (CF)를 설정합니다. 이렇게하면 jc 조건부 점프로 오류 핸들러로 쉽게 이동할 수 있습니다. ( 조건부 점프 참조)

참고 문헌

BIOS 호출 및 기타 인터럽트의 포괄적 인 목록은 Ralf Brown의 인터럽트 목록 입니다. HTML 버전은 여기 에서 찾을 수 있습니다 .

사용 가능한 것으로 자주 간주되는 인터럽트는 Wikipedia 의 목록에서 찾을 수 있습니다.

일반적으로 사용 가능한 인터럽트에 대한 심층적 인 개요는 osdev.org 에서 찾을 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow