2012-06-01 2 views
2

저는 최근에 운영 체제, 부팅 프로세스 및 NASM을 연구했습니다. 필자는 필자가 부분적으로 이해하고 가상 플로피 디스크를 통해 테스트 한 유용한 부트 스트랩 핑 코드를 발견했다. 내 기본적인 질문은 내가 이해하지 못하는 몇 가지 사항에 관한 것입니다. 내가 생각하기에 선이하는 일에 대해 의견을 말했고, 모든 수정이나 확인은 크게 감사 할 것입니다. ah 세트까지 화면에 al의 문자를 인쇄 할 int 10h 기능 Teletype output,에기본 NASM 부트 스트랩

; This is NASM 

     BITS 16     ; 16 bits! 

start:       ; Entry point 
     mov ax, 07C0h   ; Move the starting address (after this bootloader) into 'ax' 
     add ax, 288    ; Leave 288 bytes before the stack beginning for some reason 
     mov ss, ax    ; Show 'stack segment' where our stack starts 
     mov sp, 4096   ; Tell 'stack pointer' that our stack is 4K in size 

     mov ax, 07C0h   ; Use 'ax' as temporary variable for setting 'ds' 
     mov ds, ax    ; Set data segment to where we're loaded 


     mov si, text_string  ; Put string position into SI (the reg used for this!) 
     call print_string  ; Call our string-printing routine 

     jmp $     ; Jump here - infinite loop! 

     text_string db 'This is my cool new OS!', 0 ; Our null terminated string 
                ; For some reason declared after use 


print_string:     ; Routine: output string in SI to screen 
     mov ah, 0Eh    ; I don't know what this does.. 
           ; Continue on to 'repeat' 
.repeat: 
     lodsb     ; Get character from DS:SI into AL 
     cmp al, 0    ; If end of text_string 
     je .done    ; We're done here 
     int 10h     ; Otherwise, print the character (What 10h means) 
     jmp .repeat    ; And repeat 

.done: 
     ret 

     times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s 
     dw 0xAA55    ; The standard PC 'magic word' boot signature 

감사합니다,

답변

1

귀하의 의견은 대부분 정확합니다.

int 10h

은 자세한 내용은 here을 볼 수 있지만, 기본적으로 10H에 대한 호출이 기대 :

mov ah,0Eh

이는 BIOS 인터럽트 호출에 대한 매개 변수를 설정합니다 ah의 작업 및의 작업을위한 데이터.

세그먼트 레지스터는 직접로드 할 수 없으므로 레지스터에서로드 할 수 있으므로 ax을 '임시 변수'로 사용하십시오.

기본 스택 포인터에 추가 된 288 바이트는 실제로는 바이트가 아닙니다. 세그먼트 레지스터에로드 된 주소는 실제로 16 바이트 블록에 대한 포인터이므로 숫자를 실제 주소로 변환하려면 왼쪽으로 4 비트 이동하십시오. 즉, 주소 07C0h는 실제로 부트 로더 코드가있는 7C00h를 나타냅니다. 288은 16 진수 120h이므로 스택의 실제 위치는 실제로 7C00h + 1200h = 8E00h입니다.

또한 "show"및 "tell"과 같은 단어를 사용하는 것이 좋지만, sssp을 설정하여 스택 정의에 대해 생각하는 것이 좋습니다 ... 감각.

+0

아, 그래서 4608 바이트가 실제로 '도끼'에 추가되고 있습니다. . 아마도이 중 512 개는 스크립트/프로그램 자체를위한 것이고, 그 중 4096 개는 무언가에 사용됩니다. 4096은 디스크 버퍼로 사용 되는가 스택 자체를위한 것인가? 스택의 시작이나 끝으로 'ss'가 설정되어 있습니까? –

+0

@ Joesavage1 SS는 스택의베이스를 정의하고 SP는 스택에있는 위치를 정의합니다. 스택이 비어 있으면 SP는 SS에서 가장 높은 오프셋을 가리 킵니다. 즉, 물건이 스택에 푸시되고 튀어 나올 때 점진적으로 증가하면 SP가 실제로 감소합니다.SP 항상 스택에 푸시 된 마지막 항목을 가리킴 – Dougvj

+0

스택의 _start_를 나타냅니다. 그렇다면 왜 코드 자체의 저장 위치에서 4096 바이트 떨어진 위치 ('도끼')를 전달할 수 있습니까? (사물의 진입 지점에서 4608) 그들이 스택을위한 것이 아닌 경우의 4096 바이트는 무엇입니까? 또한, 왜 'ds'가 스택 작업이 완료된 후에 07C0h [7C00h]로 다시 설정되는지 알 수 있습니까? ("데이터 세그먼트를로드하는 위치로 설정하십시오") –

0
mov ah, 0Eh    ; I don't know what this does.. 

로드 0eh.

.repeat 루프는 text_string에서 al으로 각 문자를로드하고 int 10h으로 전화합니다.

+0

저는 부트 로더 사람이 아닙니다. :-)이 질문은 설정을 설명하는 답변이 있습니다 : http://stackoverflow.com/questions/3231607/stack-segment-in-the-mikeos-bootloader –