доброго времени суток ситуация (продолжаем пописывать осечку, возникли непонятки) есть com файл, он полностью загружен в память по адресу 0000:1000 (в общем случае 0000:ABC0) для того, что бы запустить тот код, надо: Код (Text): push 0090h push 0100h retf все работает... =\ не пойму, что я курил когда писал это... но, что бы правильно учитывались адреса, искомые сегмент:смещение надо привести к виду X:Y=Z:0100, X:Y - где лежит код... Z нам надо найти путем несложных мат. преобразований получаем: X*10+Y=Z*10+100 Z=(X*10+Y-100)/10 подставляя, Z=(0*10+1000-100)/10=F0 и Код (Text): push 00F0h push 0100h retf ни к чему хорошему не приводит в общем, я в заблуждении... как правильно? заранее спасибо
Управление передается, все верно. Ошибка была совсем не в ядре/загрузчике... А в процессе. Вот код: Загрузчик Код (Text): .model tiny .code org 100h entry: mov ax, 7B00h mov ss, ax mov sp, offset stkend ; цель MBR - загрузить ядро в память ; и передать ему управление ; ядро грузим в 0000:0600, сразу ; после таблицы прерываний ; каждый com-файл занимает не более ; одной дорожки, т.е. 9 килобайт ; после перемещения кода из MBR в 0000:7C00 ; состояние регистров будет слелующее: ; CS = 0 ; IP = 7C00 ; Номер сектора, дорожки, головки вычисляется так: ; Sector = ( LBA % SectorsPerTrack ) + 1 ; Cylinder = ( LBA / SectorsPerTrack ) / NumHeads ; Head = ( LBA / SectorsPerTrack ) % NumHeads ; LBA - Linear Block Address ; для дорожки после MBR значения будут: ; Sector = 1, т.к. всегда начинаем с первого, и нумерация идет с 1 ; Cylinder = 0 ; Head = 1 mov al, 12h ; читаем 18 секторов == 1 дорожка mov dl, 00h ; диск A mov dh, 01h ; первая головка mov ch, 00000000b ; номер цилиндра (дорожки), kernel на 1й дорожке mov cl, 00000001b ; номер сектора + кусок номера ; цилиндра (старшие 2 байта) mov bx, 0000h ; адрес, mov es, bx ; куда читать mov bx, 0600h ; ядро mov ah, 02h ; читаем ядро int 13h jc error ; в случае ошибки выводим сообщение ; подготовка передачи управления ядру ; для передачи управления необходимо ; установить пару CS:IP push 0050h ; записываем CS push 0100h ; записываем IP retf ; передаем управление error: mov ah, 0Eh mov bh, 00h mov al, 'M' int 10h loop1: jmp loop1 stk db 10 dup(0) label stkend end entry Ядро Код (Text): .model tiny .code org 100h entry: ; ядро приняло управление ; заводим стек mov ax, cs mov ss, ax mov sp, offset stkend ; выводим буковку K, от kernel mov ah, 0Eh mov bh, 00h mov al, 'K' int 10h mov [byte ptr cnt], 00h lprcs: ; вычисляем номер цилиндра и головки mov al, [byte ptr cnt] add al, 03h mov ah, 00h mov dl, 02h div dl mov [byte ptr cyl], al mov [byte ptr head], ah ; вычисляем адрес процесса в памяти ; в рассчете, что под процесс выделяется 1280 байт ; отсчет начинается с 0000:1000 mov ax, 0500h mov dl, [byte ptr cnt] mov dh, 00h mul dx add ax, 1100h mov [word ptr addr], ax mov al, 12h ; читаем 18 секторов == 1 дорожка mov dl, 00h ; диск A mov dh, [byte ptr head] ; mov ch, [byte ptr cyl] ; номер цилиндра (дорожки), kernel на 1й дорожке mov cl, 00000001b ; номер сектора + кусок номера ; цилиндра (старшие 2 байта) mov bx, 0000h ; адрес, mov es, bx ; куда читать mov bx, 1000h ; ядро ; mov bx, [word ptr addr] ; смещение в addr=1100+500*i mov ah, 02h int 13h ; читаем ядро jc error inc [byte ptr cnt] cmp [byte ptr cnt], 05h jne lprcs ; запускаем тестовый процесс (6й по счету) push 00F0h push 0100h retf ; ошибка чтения с диска error: mov ah, 0Eh mov bh, 00h mov al, 'E' int 10h loop1: jmp loop1 head db 1 cyl db 1 cnt db 1 addr dw 1 stk db 128 dup(0) label stkend end entry Тестовый процесс Код (Text): .model tiny .code org 100h entry: mov ax, cs mov ss, ax mov sp, offset stkend mov [word ptr tl], 0000h mov [word ptr th], 0000h loop1: ; тики будут находиться в cx:dx mov ah, 00h int 1Ah mov ax, cx mov bx, dx ; ax:bx ; cx:dx sub bx, [word ptr tl] sbb ax, [word ptr th] cmp bx, 0050h jb loop1 mov [word ptr tl], dx mov [word ptr th], cx mov ah, 0Eh mov bh, 00h mov al, '6' int 10h jmp loop1 tl dw 1 th dw 1 stk db 92 dup(0) label stkend end entry Экспериментально установил, что стек в моем случае должен быть как минимум 92 байта. Или так и надо, или я что-то недосмотрел. Почему так? В аттаче весь код + образ
Используют, ясен красен. В моем случае каждый int сбросит по три слова (cp,ip,flags), но вот почему аж 92 байта надо? Не думал, что так много...
unregistered Я имею ввиду, не сам вызов прерывания, а код обработчика, он же по идее использует тот же стек, который ты установил вначале, и в нём могут как раз и использоваться эти байты. Не было бы сессии на носу посмотрел бы, а так...