Что плохого в том, что эта сборка имеет доступ к этой строковой константе? - PullRequest
2 голосов
/ 06 мая 2011

Я думал, что начинаю понимать, что происходит, но я трачу целую вечность, пытаясь понять, почему не работает следующее:

org 0x7C00

mov ax,0x0000
mov ds,ax

mov si, HelloWorld

HelloWorld db 'Hello World',13,10,0

Я ожидаю, что инструкция mov si, HelloWorld поместит значение 0x7C08 в si (то есть 0x7c00 + смещение HelloWorld), готовое для таких вещей, как lodsb.

Когда я строю это (используя Nasm) и запускаю его (используя Bochs), я обнаруживаю, что инструкция завершения действительно выглядит так:

mov si, 0x8400

Почему это так и откуда взято значение 0x8400?

Обновление: Я обнаружил, что размещение HelloWorld в сегменте данных дает ожидаемый результат:

section .data
HelloWorld db 'Hello World',13,10,0

Почему это?

К вашему сведению, команда, использованная для построения, это nasm -f bin input.asm -o output.bin

Обновление 2 Я подсчитал, что 0x8400 равно 0x7c00 + 0x0800, где 8 - смещение HelloWorld от начала вывода - я заметил это, когда заметил, что при использовании org 0 используемый адрес 0x0800.

Я до сих пор не понимаю, что происходит, - обнаружение этого только запутало меня!

По запросу, разборка с использованием ndisasm:

00000000  B80000            mov ax,0x0
00000003  8ED8              mov ds,ax
00000005  BE0084            mov si,0x8400
00000008  48                dec ax
00000009  656C              gs insb
0000000B  6C                insb
0000000C  6F                outsw
0000000D  20576F            and [bx+0x6f],dl
00000010  726C              jc 0x7e
00000012  640D0A00          fs or ax,0xa

Ответы [ 4 ]

2 голосов
/ 06 мая 2011

Если вы не используете формат bin, nasm может переместить ваши данные в segment .data Это имеет большой смысл при компиляции в формат PE, такой как .EXE.

Другими словами, уверены ли вы, что 0x8400 не является правильным адресом после того, как выходной двоичный файл был размечен и связан? Я понимаю, что вы пытаетесь выдать данные в segment .text - для этого, я думаю, вам нужна директива bin.

Edit:

Учитывая, что вы используете формат bin и рассматриваете вашу дополнительную информацию о том, что построение строки HelloWorld в segment .data работает, я подозреваю, что вам нужно сделать следующее:

lea si, [cs:HelloWorld]

Возможно, я не включился в синтаксис - прошло много лет с тех пор, как я кодировал в 16-битном x86 - но дело в том, что вы получаете смещение на основе предположения о значении ds, которое явно очищаются и могут предположить, что ассемблер имеет значение segment .code или подобное. (Спасибо Аарону за то, что он исправил мой мов на выход.)

1 голос
/ 07 мая 2011

Обновите свою копию NASM.

Используя nasm 2.09rc1, я получаю следующую (неожиданную) разборку:

00000000  B80000            mov ax,0x0
00000003  8ED8              mov ds,ax
00000005  BE0084            mov si,0x8400
00000008  48                dec ax
00000009  656C              gs insb
0000000B  6C                insb
0000000C  6F                outsw
0000000D  20576F            and [bx+0x6f],dl
00000010  726C              jc 0x7e
00000012  640D0A00          fs or ax,0xa

Используя nasm 2.09.08, я получаю следующую (ожидаемую) разборку:

00000000  B80000            mov ax,0x0
00000003  8ED8              mov ds,ax
00000005  BE087C            mov si,0x7c08
00000008  48                dec ax
00000009  656C              gs insb
0000000B  6C                insb
0000000C  6F                outsw
0000000D  20576F            and [bx+0x6f],dl
00000010  726C              jc 0x7e
00000012  640D0A00          fs or ax,0xa

Я думаю, это был кандидат на освобождение по причине ...:)

1 голос
/ 06 мая 2011

С MASM Справка:

Первый объектный файл, содержащий код должен начать свой сегмент кода с линия как RESB 100h. Это к убедитесь, что код начинается со смещения 100 ч относительно начала сегмент кода, так что компоновщик или Программа конвертера не должна настроить адрес ссылки в пределах файл при создании файла .COM. Другие ассемблеры используют директиву ORG для этого, но ORG в NASM является специфичная для формата директива для корзины Формат вывода и не означает то же самое, что и в MASM-совместимые ассемблеры.

Итак, у вас есть сегмент кода CS и сегмент данных DS, и они не равны, поэтому указатели меток также различны, в зависимости от раздела. В x86 выравнивание раздела обычно составляет 4096 байт, что соответствует размеру страницы памяти.

0 голосов
/ 06 мая 2011

Хмм ... "Н" - это 0x48.Возможно, вы извлекаете первый байт «Hello World» вместо его адреса.

...