2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3, 4  След.
 
 Hello world [асcемблер]
Сообщение08.06.2013, 22:09 
Заслуженный участник
Аватара пользователя


03/08/11
1613
Новосибирск
Привет, почитываю Зубкова- Ассемблер...! Пытаюсь разобраться в первой программе на ассемблере. Есть код
Используется синтаксис ASM
.model tiny
.data
message db 'Hello world! $'
.code
org 100h
start:
mov ah,09h
mov dx, 0
int 21h
ret
end start

Если написать mov dx,offset message то в принципе все хорошо, но... Не понимаю, почему выводится это:
Изображение
А если написать
Используется синтаксис ASM
.model tiny
.data
message db 'Hello world! $'
.code
org 100h
start:
mov ah,09h

int 21h
ret
end start

то вылетает
Изображение
Открываю debugger
Изображение
перемещаюсь на два шага вперед и завершается:
Изображение
Не понятно, почему регистр EAX не меняется, я же в ah пихаю 09h? Откуда в EDX 0327061E сразу после входа в hello.com? Еще хотелось бы понять, что означает callback 0010, гугляж в этом вопросе не помог.

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 22:27 
Заслуженный участник


29/04/12
268
Первый код не работает, потому что строка message находится не по адресу 0. Ибо сначала идёт код, а данные в конце. Это же COM: система начинает его исполнять как код, начиная с первого байта.

Надо писать "offset message" (или просто "message" -- вроде бы у masm и tasm в этом плане разные соглашения) и компилятор сам подставит нужный адрес.

Второй код не работает, потому что вы в dx ничего не записали. Соответственно там мусор изначально.

P. S. Я не знаю, что за отладчик, но меня жутко смущают 32-битные регистры eax, ebx и т. д. COM-программы всегда 16-битные. Кстати, у TASM есть собственный отладчик.

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 22:46 
Заслуженный участник


11/11/07
1198
Москва
lena7 в сообщении #734481 писал(а):
COM-программы всегда 16-битные.

Если процессор позволяет, то можно хоть с 64-битными регистрами работать.

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 23:01 
Заслуженный участник


29/04/12
268

(Оффтоп)

AV_77 в сообщении #734484 писал(а):
Если процессор позволяет, то можно хоть с 64-битными регистрами работать.

Процессор-то может и позволяет, но система будет всегда смотреть на COM как на 16-битную программу и, соответственно, выполнять будет в этом режиме. У программы даже не будет прямого доступа к процессору и другим аппаратным средствам, ибо на не совсем древних Windows этот 16-битный режим получается за счёт виртуальной DOS-машины (NTVDM).

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 23:06 
Заслуженный участник
Аватара пользователя


03/08/11
1613
Новосибирск
lena7 в сообщении #734481 писал(а):
Надо писать "offset message"

Это понятно, но почему при записи в dx 0 он сперва выводит нейпойми че, а потом hello world и больше ничего потом не выводит? В сегменте данных помимо 'hello world' уже было что-то и я получил весь сегмент в консоль?
lena7 в сообщении #734481 писал(а):
Второй код не работает, потому что вы в dx ничего не записали

Я думал, что если мы ничего не запишем в регистр, то там будут нули. Или системой туда могло быть записано что-то раньше?
lena7 в сообщении #734481 писал(а):
P. S. Я не знаю, что за отладчик, но меня жутко смущают 32-битные регистры eax, ebx и т. д. COM-программы всегда 16-битные. Кстати, у TASM есть собственный отладчик.

Это dosbox-отладчик. Вы рекуомендуете его не использовать?

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 23:15 
Заслуженный участник


09/09/10
3729
xmaister в сообщении #734492 писал(а):
Это понятно, но почему при записи в dx 0 он сперва выводит нейпойми че, а потом hello world и больше ничего потом не выводит? В сегменте данных помимо 'hello world' уже было что-то и я получил весь сегмент в консоль?

Когда COM-файл грузится в память, он размещается по смещению 100h, а вовсе не 0h. Первые 256 байт — всякая служебная информация DOS. Соответственно, вы ее и выводите на экран.

xmaister в сообщении #734492 писал(а):
Я думал, что если мы ничего не запишем в регистр, то там будут нули.

Почему? Там будет то, что было до вас. Насколько я помню, никаких гарантий на содержимое регистров общего назначения система не дает.

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 23:15 
Заслуженный участник


11/11/07
1198
Москва
lena7 в сообщении #734491 писал(а):
Процессор-то может и позволяет, но система будет всегда смотреть на COM как на 16-битную программу и, соответственно, выполнять будет в этом режиме. У программы даже не будет прямого доступа к процессору и другим аппаратным средствам, ибо на не совсем древних Windows этот 16-битный режим получается за счёт виртуальной DOS-машины (NTVDM).

Команды выполняет процессор и если он может данную команду декодировать, то он ее выполнит. И не важно какая она будет 16-битная или 64-битная. За работу с регистрами отвечает процессор, операционная система про это не знает.

 Профиль  
                  
 
 Re: Hello world
Сообщение08.06.2013, 23:16 
Заслуженный участник


29/04/12
268
xmaister в сообщении #734492 писал(а):
Это понятно, но почему при записи в dx 0 он сперва выводит нейпойми че, а потом hello world и больше ничего потом не выводит? В сегменте данных помимо 'hello world' уже было что-то и я получил весь сегмент в консоль?

В COM нет сегментов кода, данных и т. д. Это просто плоский бинарный файл, без какой-либо структуры (в отличии от EXE, например). Файл сразу начинается с кода ("mov ah,9" и т.д.), после последней команды ("ret") сразу начинаются данные "hello world! $". Поэтому, когда вы в dx записали 0, программа у вас вывела на экран PSP (служебная информация, 256 байт), затем всё содержимое файла, вплоть до доллара. Доллар -- это символ конца строки в DOS. Поэтому вывод на нём остановился.

xmaister в сообщении #734492 писал(а):
Или системой туда могло быть записано что-то раньше?

Один бог знает, что там. Вообще, может система что-то конкретное и гарантирует, но полагаться на это -- плохая идея. Если вы хотите, чтобы в регистре было какое-то значение -- запишите его.

-- 09.06.2013, 00:22 --

(Оффтоп)

AV_77 в сообщении #734496 писал(а):
Команды выполняет процессор и если он может данную команду декодировать, то он ее выполнит. И не важно какая она будет 16-битная или 64-битная. За работу с регистрами отвечает процессор, операционная система про это не знает.

Вы не правы. Во-первых, система декодирования команд разная для 16-, 32- и 64-битного режима. Одна и та же последовательность байт в разных режимах означает разное, вообще говоря. Во-вторых, как я уже писала, 16-битный режим в не совсем древних Windows получается за счёт виртуальной машины. То есть на самом деле процессор в 16-битный режим даже не переходит. Программа не попадает к процессору напрямую, а обрабатывается NTVDM.

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 00:28 
Заслуженный участник
Аватара пользователя


03/08/11
1613
Новосибирск
Joker_vD в сообщении #734495 писал(а):
Когда COM-файл грузится в память, он размещается по смещению 100h, а вовсе не 0h.

А, теперь понятно зачем org 100h. Соответственно после начала выполнения в регистре IP будет 100h?
lena7 в сообщении #734498 писал(а):
В COM нет сегментов кода, данных и т. д. Это просто плоский бинарный файл, без какой-либо структуры (в отличии от EXE, например). Файл сразу начинается с кода ("mov ah,9" и т.д.), после последней команды ("ret") сразу начинаются данные "hello world! $". Поэтому, когда вы в dx записали 0, программа у вас вывела на экран PSP (служебная информация, 256 байт), затем всё содержимое файла, вплоть до доллара. Доллар -- это символ конца строки в DOS. Поэтому вывод на нём остановился.

Спасибо за подробное разъяснение! Но мне не совсем понятно, директиву .data я убрал и строку message поместил после ret. Если я попытаюсь убрать директиву .code то прога не ассемблируется, она должна обязательно присутствовать в любой программе?

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 00:52 
Заслуженный участник


29/04/12
268
xmaister в сообщении #734511 писал(а):
Соответственно после начала выполнения в регистре IP будет 100h?

Да.

xmaister в сообщении #734511 писал(а):
Но мне не совсем понятно, директиву .data я убрал и строку message поместил после ret. Если я попытаюсь убрать директиву .code то прога не ассемблируется, она должна обязательно присутствовать в любой программе?

Хотя бы один сегмент должен быть. Это нужно компилятору для создания объектного файла.

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 08:18 
Заслуженный участник


11/11/07
1198
Москва
lena7 в сообщении #734498 писал(а):
Вы не правы. Во-первых, система декодирования команд разная для 16-, 32- и 64-битного режима.

1) Нет таких режимов. Ну почитайте учебники, что-ли. В интеловских процессорах есть режимы:
- реальный;
- защищенный;
- виртуального 8086.
Отличие этих режимов заключается в обработке адресов и доступности некоторых (дополнительных) привилегированных команд. Работа с 16-ти и 32-битными регистрами в перечень таких команд не входит. Поэтому в любом режиме процессор может работать с любым регистром общего назначения.

2) Если работа выполняется на виртуальной машине, то и здесь перечень команд определяется эмулируемым процессором, а не режимом работы.

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 12:40 
Заслуженный участник


29/04/12
268

(Оффтоп)

AV_77 в сообщении #734553 писал(а):
Нет таких режимов. Ну почитайте учебники, что-ли.

Учебников по этой теме я уже начиталась, когда писала дизассемблер для Pentium 4 Prescott.

"16-, 32- и 64-битные режимы" -- вольность речи, я просто не хотела углублять оффтоп. Режимы имеют собственные названия и характеризуются, конечно, не только разрядностью. На 386 есть три режима, которые вы назвали. По мере эволюции линейки x86 набор режимов изменялся. Причина появления режимов -- желание сохранить обратную совместимость, когда происходят кардинальные изменения типа изменения разрядности, системы адресации и др.

Реальный режим -- это 16-битный режим со старой сегментной адресацией, для совместимости с x86-16. В этом режиме процессор использует другую систему декодирования команд, нежели в 32-битном защищённом режиме. Например, вот так процессор понимает одну и ту же последовательность байт в этих режимах:
Код:
; реальный режим (16 бит)
B8 42 00            mov ax, 0042h
00 00               add [bx+si], al

; защищённый режим (32 бита)
B8 42 00 00 00      mov eax, 00000042h


В реальном режиме, однако, имеется лазейка для доступа к новым возможностям процессора. Самое главное -- механизм для перевода процессора в защищённый режим (ибо x86 всегда стартуют в реальном режиме). Также с помощью специального префикса можно выполнять некоторые операции с 32-битными регистрами eax и др. Поэтому отчасти вы правы, AV_77. Но эти префиксы предоставляют слишком ограниченный набор манипуляций с 32-битными регистрами и назвать реальный режим воистину 32-битным язык не поворачивается вообще никак. Доступа к 64-битным регистрам rax и др. нет, даже если процессор их имеет.

В x86-64 есть также 64-битный длинный режим (long) и 32-битный режим совместимости (legacy), позволяющий работать на x86-64 как если бы это был x86-32. Однако режим совместимости на x86-64 не предоставляет никаких лазеек для доступа к 64-битным регистрам процессора.

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 18:25 
Заслуженный участник
Аватара пользователя


03/08/11
1613
Новосибирск
lena7 в сообщении #734498 писал(а):
Это просто плоский бинарный файл, без какой-либо структуры (в отличии от EXE, например).

Хотелось бы сделать уточнение. У нас есть сегменты по 64кб и в один из таких сегментов загружается сначала команды процессора потом данные. А что если код с данными в таком .com файле занимают >64кб?

Если использовать модель памяти small то у нас будет 2 сегмента по 64 кб, при этом если я попытаюсь собрать .exe файл, то будет No stack, значит он там отдельно от данных? Или в моделе tiny отдельно от данных с кодом, я правильно понял?

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 19:04 
Заслуженный участник


29/04/12
268
xmaister в сообщении #734699 писал(а):
А что если код с данными в таком .com файле занимают >64кб?

В COM-программах нет раздельных сегментов кода, данных, стека и т.д. -- там всё в одном сегменте. В частности, указатель стека по умолчанию установлен на конец сегмента (стек растёт вниз). То есть, после загрузки системой COM-фала, соотв. сегмент в памяти будет выглядеть так:
Код:
0       PSP
100h    код
        данные
        ...
FFFFh   конец стека

Размер сегментов в реальном режиме фиксирован -- 64 кб. Следовательно, не бывает COM-программ больших 64 кб.

Если нужно больше, вам нужен формат EXE. В этом случае данные, код и стек можно раскидать по разным сегментам.

Учтите, что система при загрузке исполняемого файла устанавливает только регистр cs (code segment), указывающий на тот сегмент, где будет код (то есть куда указывает IP). Сегменты данных (ds) и др. вы должны инициализировать вручную. Это должно быть в вашем учебнике.

Модель tiny -- это для COM (где один сегмент для всего). В модели small два сегмента: в одном код, во втором данные и стек.

"No stack" -- это, видимо, предупреждение, а не ошибка. Можно игнорировать, я думаю. Но лучше успокоить компилятор, указав размер стека директивой .stack.

 Профиль  
                  
 
 Re: Hello world
Сообщение09.06.2013, 20:00 
Заслуженный участник
Аватара пользователя


03/08/11
1613
Новосибирск
lena7 в сообщении #734711 писал(а):
Модель tiny -- это для COM (где один сегмент для всего). В модели small два сегмента: в одном код, во втором данные и стек.

Я создавал .com файл указывая в начале .model small, при этом все собралось без ошибок и предупреждений. Значит эта строка было проигнорирована?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 49 ]  На страницу 1, 2, 3, 4  След.

Модераторы: maxal, Toucan, PAV, Karan, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group