Странное расположение памяти при создании констант в NASM - PullRequest
0 голосов
/ 06 января 2012

Рассмотрим следующий код ассемблера для частичного загрузчика:

bits 16
org 0x7C00

msg_init db 'Initializing...', 0Ah, 0Dh, 0
msg_completed db 'Completed', 0Ah, 0Dh, 0

jmp start

start:
    xor ax, ax              
    mov ds, ax              
    mov es, ax              

    mov si, msg_init        
    call print              

    mov si, msg_completed   
    call print              

    mov al, '*'
    mov bx, 0
    mov ah, 0Eh
    int 10h

    cli
    hlt

print:
    lodsb                   ; al = [ds:si] - char to write
    or al, al               ; set zero flag if al=0
    jz return               ; jump to return if zero flag set
    mov bx, 0               ; bh = page #, bl = color
    mov ah, 0Eh             ; function = teletype output
    int 10h             ; video interrupt
    jmp print               ; print next char if not zero

return:
    ret                 ; return

times 510-($-$$) db 0
dw 0xAA55   

Структура памяти выглядит следующим образом:

0000: 49 6e 69 74 69 61 6c 69-7a 69 6e 67 2e 2e 2e 0a Initializing....
0010: 0d 00 43 6f 6d 70 6c 65-74 65 64 0a 0d 00 e9 00 ..Completed.....
0020: 00 31 c0 8e d8 8e c0 be-00 7c e8 11 00 be 12 7c .1.......|.....|
0030: e8 0b 00 b0 2a bb 00 00-b4 0e cd 10 fa f4 ac 08 ....*...........
0040: c0 74 09 bb 00 00 b4 0e-cd 10 eb f2 c3 00 00 00 .t..............

Когда я изменяю константу msg_completed на «Включено», т.е. msg_completed db 'Enabled', 0Ah, 0Dh, 0 расположение памяти меняется на:

0000: 00 f0 e3 fe 00 00 2e 0a-00 00 15 7c 00 00 57 2a ...........|..W*
0010: 0d 00 45 6e 61 62 6c 65-64 0a 0d 00 e9 00 00 31 ..Enabled......1
0020: c0 8e d8 8e c0 be 00 7c-e8 11 00 be 12 7c e8 0b .......|.....|..
0030: 00 b0 2a bb 00 00 b4 0e-cd 10 fa f4 ac 08 c0 74 ..*............t
0040: 09 bb 00 00 b4 0e cd 10-eb f2 c3 00 00 00 00 00 ................

Кажется, первые несколько байтов перезаписаны. Есть идеи?

1 Ответ

1 голос
/ 06 января 2012

Я не наблюдаю такого поведения (пробовал «версию 0.98.36, скомпилированную 13 июня 2003 года» и «версию 2.09.10, скомпилированную 15 июля 2011 года» в Windows XP).«Инициализация» есть во всех 4 двоичных файлах.

Вы уверены, что больше ничего не меняли?И двоичный файл во втором случае - это то, что выводит NASM, а не то, что вы читаете с носителя?

Кстати, ваш код не будет работать.Процессор начнет выполнять загрузочный сектор с самого начала, с db 'Initializing...', 0Ah, 0Dh, 0.Это данные, а не код.

Кроме того, было бы хорошо убедиться, что CS=0 и IP>=0x7C00 в начале кода (некоторые BIOS переходят на 0x7C0:0 вместо 0:0x7C00) и очищаютFLAGS.DF с CLD до LODSB.

...