Я изучил инструкцию org
и другую документацию, и я понимаю, что происходит.
Согласно документации NASM в директиве org
, сокращение от или i g in:
Функция директивы ORG состоит в том, чтобы указать исходный адрес, с которого NASM будет считать, что программа начинается при загрузке в память. [...] ORG NASM делает именно то, что говорит директива: происхождение. Его единственная функция - указывать одно смещение, которое добавляется ко всем внутренним адресным ссылкам в разделе.
Следовательно, компилятор NASM предполагает, что программа будет загружена по адресу, указанному в инструкции origin (т.е. org
). BIOS делает именно это. Согласно следующего , как только BIOS обнаружит допустимый загрузочный сектор, который содержит действительную загрузочную подпись, загрузчик будет " загружен в память в 0x0000: 0x7c00 (сегмент 0, адрес 0x7c00)".
Из приведенной выше цитаты, когда в документации NASM говорится «ссылки на внутренние адреса», это относится ко всем ссылкам на конкретные области памяти, которые используются в коде (например, ссылка на метку и т. Д.). Например, строка в коде загрузчика выше: mov si, bootmsg
разрешит bootmsg
до 0x07c00 + offset
, где смещение определяется положением первого байта моей строки bootmsg
(то есть 'W').
С моим кодом выше, если я разбираю bin-файл с помощью утилиты ndisasm , я вижу следующее:
00000000 EB2C jmp short 0x2e
00000002 57
00000003 656C
00000005 636F6D
00000008 6520746F
0000000C 206D79
0000000F 204F70
00000012 657261
00000015 7469
00000017 6E
00000018 67205379
0000001C 7374
0000001E 656D
00000020 2100
00000022 AC lodsb
00000023 08C0 or al,al
00000025 7406 jz 0x2d
00000027 B40E mov ah,0xe
00000029 CD10 int 0x10
0000002B EBF5 jmp short 0x22
0000002D C3 ret
0000002E 31C0 xor ax,ax
00000030 8ED8 mov ds,ax
00000032 8EC0 mov es,ax
00000034 BE027C mov si,0x7c02
00000037 E8E8FF call 0x22
0000003A FA cli
0000003B F4 hlt
00000... ... ...
(я удалил сгенерированные инструкции с 0x00000002 до 0x00000020, потому что это моя строка bootmsg
, представляющая данные, а не код).
Как видно из выходной сборки, по адресу 0x00000034 мой bootmsg
был заменен на 0x7c02 (например, 0x7c00 + смещение = 0x02).
Майкл Петч также дал очень твердое понимание. Распространенным заблуждением считается то, что загрузчик загружен в 0x7c0: 0x0000 (сегмент 0x07c0, смещение 0). Хотя технически это можно использовать, но вместо этого было стандартизировано использование смещения сегмента, равного нулю ( Хорошая практика - применять CS: IP в самом начале загрузочного сектора ). Как уже упоминал Майкл, если вам нужна дополнительная информация, обратитесь к разделу 4 следующего руководства по адресации смещения сегмента .