2017-04-12 13 views
4

일반적으로 프로그래머는 부트 로더의 맨 처음 줄에 레지스터 (때로는 세그먼트)를 고정시켜 주며 일반적으로이를 조언합니다. 예를 들어 :부트시 기본 레지스터 및 세그먼트 값

inc cx 
dec bx 
inc bp 
dec di 
xor ax, ax 

나는 내가 알고하는 것을 궁금해 : BIOS는 부팅 절차를 수행하는 동안 모든 레지스터을 지 웁니다.

부트 로더에서 레지스터와 세그먼트를 초기화하는 것이 좋은 습관입니까? 그렇다면 기본 레지스터, 세그먼트 및 포인터 값 (어쩌면 칩셋에 따라 다름)은 무엇입니까?

+2

인텔 설명서에서는 CPU의 전원을 켤 때 각 레지스터에 포함되는 값을 지정합니다. 하지만 BIOS가 부트 로더에 손을 놓은 후 상태에 대해 묻는 중입니다. – Nayuki

+0

고맙습니다. @ 나유키. 당신 말이 맞아요. –

+6

부트 로더가 실행될 무렵에는 단 한 가지만 추측 할 수 있습니다 (1980 년대를 제외하고는 호환되지 않는 컴퓨터 제외). 즉, BIOS에 의해 부팅 된 드라이브 번호가 _DL_ 레지스터에 있으므로 플래그 상태, 세그먼트 레지스터 상태 및 범용 레지스터 상태에 대한 가정을하지 않아야합니다. –

답변

3

세그먼트 레지스터의 설정에 대해 언급 했으므로 코드가 16 비트 코드 인 것처럼 보입니다. 기존 IBM-PC 부트 로더 (PC-BIOS)에 대해 논의 중이며 EFI/UEFI가 아닌 것으로 간주합니다. 제조 된 장비의 대다수를위한 레거시 부트 로더에는 사용자가 거의 생각할 수있는 것이 거의 없습니다.

PC-BIOS가 사용 가능한 부트 장치에서 부트 섹터를로드하고 그에 대한 제어를 전송할 때가지만 모든 레지스터의 상태는 사용 가능한 값을 갖습니다. 80 및 90에서 일부 비표준 (및 100 % 호환 BIOS가 아닌)을 제외하고 레지스터 DL에는 BIOS가 부팅 된 부팅 드라이브 번호가 포함됩니다. 이 값은 Int 13h disk service routines을 호출하는 데 사용 된 값이기도합니다.

SS : SP은 RAM의 어느 지점을 가리킬 가능성이 있지만 BIOS와 BIOS가 다른 점을 지적합니다. 특히 데이터를 메모리에로드하려는 경우 자체 스택 포인터 (SSSP)를 설정해야합니다. 자신이 특별히 설정하지 않는 한 의도하지 않게 스택으로 데이터를 덮어 쓸 수 있습니다. IP 항상 0000으로 설정됩니다 : 0x7c00 (CS = 0000, IP = 0x7c00) 제어를 부트 로더로 전송 될 때 (보통 FAR JMP을 통해)

일부는 CS가 있다고 주장한다. 불행히도 이것은 보장되지 않습니다. 일부 부트 로더는 물리적 주소 0x07c00 (0x07c0 < < 4 + 0x0000)을 가리키는 0x07c0 : 0x0000을 사용하는 것으로 알려져 있습니다. 이는 서로 다른 segment:offset addressing이 동일한 실제 주소 (예 : 0x07c00)를 나타낼 수 있기 때문입니다. 나는 을 작성하여 으로 가정하면 CS은 항상 0x0000이되어 환경에 따라 몇 가지 흥미로운 버그가 발생할 수 있습니다.

문자열 명령어 (CMPSMOVS과 같은)에 사용되는 방향 플래그 (FLAGS 레지스터의 DF)는 특정 방향으로 가정하면 안됩니다. 대부분의 코드는 순방향 이동 (DF = 0)을 사용하지만 BIOS가 부트 로더로 점프하기 전에 설정 한 방향이라는 보장은 없습니다. 따라서 앞쪽으로 이동하려면 CLD으로 명시 적으로 지우거나 뒤로 이동하려면 STD으로 설정해야합니다.

위의 DL 레지스터 외에도 범용 레지스터가 전혀 초기화되지 않는다고 가정해서는 안됩니다. 종종 제로라고 가정하는 부트 로더를 봅니다. 이것은 거의 결코 사실이 아닙니다.

많은 것들이 내 Stackoverflow General Bootloader Tips에서 논의되었습니다.

+1

감사합니다. 그건 그렇고, 나는 BIOS에 태그를 추가했다. –