Обьясните плиз
Модератор: Andy
Здраствуйте!
Я недавно начал изучать Ассемблер и у меня возникло несколько вопросов и проблем при написании програмы. Пишу я на masm32 очень простую програму которая выводит сообщение на экран, вот код:
.186
.model small
.data
Message db 'Hello!$'
.code
_start:
mov dx,offset Message
mov ah,09h
int 21h
end _start
И вот мои вопросы:
1. В том виде котором я написал код он ассемблируетса нормально но как только я заменяю .186 на .386 тут же высвечиваетса ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(7) : error A2022: instruction operands must be the same size
2. Если убрать символ нижнего подчеркивания перед start то выйдет ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(10) : warning A4023: with /coff switch, leading underscore required for start address : start
3. После того как я ассемблирую этот код ( при этом никаких ошыбок необнаружываетса ), я его соединяю с файлом obj но при этом тоже выдаетса ошыбка уже при линковке:
Test_1.obj : fatal error LNK 1190: invalid fixup found, type 0x0001
_
Link error
Помогите пожалуйста разобратса. Если неуспеваетсе ответить на все вопросы то ответьте хотя бы на №3 чтобы я понял почему код неработает. Заранее спасибо.
Я недавно начал изучать Ассемблер и у меня возникло несколько вопросов и проблем при написании програмы. Пишу я на masm32 очень простую програму которая выводит сообщение на экран, вот код:
.186
.model small
.data
Message db 'Hello!$'
.code
_start:
mov dx,offset Message
mov ah,09h
int 21h
end _start
И вот мои вопросы:
1. В том виде котором я написал код он ассемблируетса нормально но как только я заменяю .186 на .386 тут же высвечиваетса ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(7) : error A2022: instruction operands must be the same size
2. Если убрать символ нижнего подчеркивания перед start то выйдет ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(10) : warning A4023: with /coff switch, leading underscore required for start address : start
3. После того как я ассемблирую этот код ( при этом никаких ошыбок необнаружываетса ), я его соединяю с файлом obj но при этом тоже выдаетса ошыбка уже при линковке:
Test_1.obj : fatal error LNK 1190: invalid fixup found, type 0x0001
_
Link error
Помогите пожалуйста разобратса. Если неуспеваетсе ответить на все вопросы то ответьте хотя бы на №3 чтобы я понял почему код неработает. Заранее спасибо.
Директива .386 подразумевает после себя 32-разрядные инструкции и адрессацию. Т.е. теперь смещения станут 32 битные, и команда должна выглядеть как" писал(а):1. В том виде котором я написал код он ассемблируетса нормально но как только я заменяю .186 на .386 тут же высвечиваетса ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(7) : error A2022: instruction operands must be the same size
mov edx, offset message
По-умолчанию константа/метка start уже определена, рекомендуют добавить подчеркивание, или назвать по-другому" писал(а):2. Если убрать символ нижнего подчеркивания перед start то выйдет ошыбка:
Assembling: G:\masm32\Test_1.asm
G:\masm32\Test_1.asm(10) : warning A4023: with /coff switch, leading underscore required for start address : start
Данная ошибка мне не известна, она связана с неверным компоновочным модулем в объектом файле, что то видать не срослось между компилятором и линковщиком. Попробуйте поставить более свежий линковщик, который внятно поймет что там нацарапал этот ненавистный мною masm32" писал(а):3. После того как я ассемблирую этот код ( при этом никаких ошыбок необнаружываетса ), я его соединяю с файлом obj но при этом тоже выдаетса ошыбка уже при линковке:
Test_1.obj : fatal error LNK 1190: invalid fixup found, type 0x0001
It's a long way to the top if you wanna rock'n'roll
Спасибо за ответ. Я поменял линковщик на более новый и теперь все работает.
Опять нужна ваша помощь!
Пытаюсь написать програму которая выводит на экран число.
Вот код:
Теперь мои вопросы:
№1. Насколько я понял две команды
mov ax,@data
mov ds,ax
это команды которые оределяют адрес сегмента кода. Обязательно ли их использывать? Просто я встречал код и без этих двух команд.
№2.
Правильно ли, что регистры SI и DI это регистры где хранятса смещение даных, которые должны быть перемещены (регистр SI) и смещение даных, куда должно будет шото помещено (регистр DI). Если это правильно то просто напишыте "Да". Я по этому определению и написал строку "mov di,offset Result" поскольку я буду в Result помещать другие данные.
№3
Главный вопрос:
В результате запуска програмы вместо цифры 2 выводиста всякий мусор и издаетса дикий писк
Я так понимаю что неправильно перевел двоичное число в строку.
Я действовал за схемой делим на 10 к остатку прибавляем 30h или символ "0" и в итоге получаем ASCII код нужной цифры. Поскольку в описании команды div было указано что делимое должно по размеру быть в два раза больше делителя то 10 я занес в сh, поскольку ax это 16 бит --- то нам нада было 8 бит для делителя тоесть сh.
За тем же описанием было сказано, остаток хранитса в регистре ah. Я поменял местами ah и al и использывал команду stosb которая должна загрузить al в Result. Потом вернул все на место. Чтобы строка нормально выводилась в конце добавил знак $ таким же способом, тоесть занес его в al и использывал команду stosb. Потом просто загрузил в dx уже хранящиеся в di смещение Result'a и вызвал прерывание для вывода на экран --- но нечего неполучилось.
№4
Я хотел чтобы програма завершалась путем нажатия клавиш Сtrl+Break для этого занес в al 01, а в ah 4с --- но в итоге прога просто пропищала высветила шото непоянтное и сама закрылась недожыдаясь нажатия клавиш.
Помогите пожалуйста ещо раз!
Пытаюсь написать програму которая выводит на экран число.
Вот код:
Код: Выделить всё
.186
.model tiny
.stack 100h
.data
Number = 2
Result db ''
.code
_start:
mov ax,@data
mov ds,ax
mov di,offset Result
mov ax,Number
mov ch,10
div ch
add ah,'0'
xchg al,ah
stosb
xchg al,ah
mov al,'$'
stosb
mov dx,di
mov ah,09h
int 21h
mov ax,4c01h
int 21h
end _start
№1. Насколько я понял две команды
mov ax,@data
mov ds,ax
это команды которые оределяют адрес сегмента кода. Обязательно ли их использывать? Просто я встречал код и без этих двух команд.
№2.
Правильно ли, что регистры SI и DI это регистры где хранятса смещение даных, которые должны быть перемещены (регистр SI) и смещение даных, куда должно будет шото помещено (регистр DI). Если это правильно то просто напишыте "Да". Я по этому определению и написал строку "mov di,offset Result" поскольку я буду в Result помещать другие данные.
№3
Главный вопрос:
В результате запуска програмы вместо цифры 2 выводиста всякий мусор и издаетса дикий писк

Я действовал за схемой делим на 10 к остатку прибавляем 30h или символ "0" и в итоге получаем ASCII код нужной цифры. Поскольку в описании команды div было указано что делимое должно по размеру быть в два раза больше делителя то 10 я занес в сh, поскольку ax это 16 бит --- то нам нада было 8 бит для делителя тоесть сh.
За тем же описанием было сказано, остаток хранитса в регистре ah. Я поменял местами ah и al и использывал команду stosb которая должна загрузить al в Result. Потом вернул все на место. Чтобы строка нормально выводилась в конце добавил знак $ таким же способом, тоесть занес его в al и использывал команду stosb. Потом просто загрузил в dx уже хранящиеся в di смещение Result'a и вызвал прерывание для вывода на экран --- но нечего неполучилось.
№4
Я хотел чтобы програма завершалась путем нажатия клавиш Сtrl+Break для этого занес в al 01, а в ah 4с --- но в итоге прога просто пропищала высветила шото непоянтное и сама закрылась недожыдаясь нажатия клавиш.
Помогите пожалуйста ещо раз!
Читайте в книжках про PSP-сегменты, там вполне понятно написано какими значениями будут инициализированы сегментные регистры при запуске программы, если вы не уверены - запишите значения вручную." писал(а):№1. Насколько я понял две команды
mov ax,@data
mov ds,ax
это команды которые оределяют адрес сегмента кода. Обязательно ли их использывать? Просто я встречал код и без этих двух команд.
Значения регистров SI и DI как смещений операндов источника и приемника обязательы лишь при использовании строковых команд, таких как MOVS, SCAS, CMPS, STOS, INS и т.д. Если вы не используете эти команды, смещения операндов источника и назначения можете загружать в любой регистр, для которого допустима адресация в реальном режиме. В защищенном режиме можете использовать любой регистр общего назначения." писал(а):№2.
Правильно ли, что регистры SI и DI это регистры где хранятса смещение даных, которые должны быть перемещены (регистр SI) и смещение даных, куда должно будет шото помещено (регистр DI). Если это правильно то просто напишыте "Да". Я по этому определению и написал строку "mov di,offset Result" поскольку я буду в Result помещать другие данные.
После последней команды Stosb, содержимое регистра DI указывает на первый байт после вашей строки. Затем вы подготавливаете параметры для вывода этой строки, но в регистре DX должно находиться смещение начала вашей строки а не конца. В результате выводиться то, что находиться после этой самой строки, а именно - ваш код, данные ОС и т.д., в которых по-любому где-то встречаеться символ с кодом 7, который для системы вывода означает команду выдать звуковой сигнал. Все это будет продолжаться до тек пор, пока не встретится символ "$"." писал(а):№3
Главный вопрос:
В результате запуска програмы вместо цифры 2 выводиста всякий мусор и издаетса дикий писк Я так понимаю что неправильно перевел двоичное число в строку.
А она и не должна ничего ждать, то что заноситься в AL будет доступно операционной системе как код ошибки, которую она может прочитать во внутренней переменной ERRORCODE и тем самым выполнять определенные действия. Читайте документацию к функциям MS-DOS и внимательно следите за содержимым регистров и все у вас получиться." писал(а):№4
Я хотел чтобы програма завершалась путем нажатия клавиш Сtrl+Break для этого занес в al 01, а в ah 4с --- но в итоге прога просто пропищала высветила шото непоянтное и сама закрылась недожыдаясь нажатия клавиш.
It's a long way to the top if you wanna rock'n'roll
определяют адрес сегмента данныхApokal писал(а):№1. Насколько я понял две команды
mov ax,@data
mov ds,ax
это команды которые оределяют адрес сегмента кода. Обязательно ли их использывать? Просто я встречал код и без этих двух команд.
по умолчанию при загрузке указывает на PSP
для программ типа COM инициализация требуется, так как вся программа 1 сегмент
при использовании строковых комант обратите внимание с каким сегментом работает приемник, т.е. с чем в паре работает DI
Спасибо что ответили.
Но у меня опять нечего неполучилось хотя прогрес кое какой есть. В коде я заменил строку mov dx,di на mov dx,offset Result. Но на экране тот же результат хотя мусора и писка стало раза в 3 меньше. Я даже скачал СodeView и там проследил за всемя регистрами ----- все происходило правильно и в конце в dx было смещение Result'a.
Единственное что, так это я незнаю как просмотреть содержимое Result'a. При попытке просмотреть в СodeView выдало сообщение:
"Expresion cannot be evaluated"
Но у меня опять нечего неполучилось хотя прогрес кое какой есть. В коде я заменил строку mov dx,di на mov dx,offset Result. Но на экране тот же результат хотя мусора и писка стало раза в 3 меньше. Я даже скачал СodeView и там проследил за всемя регистрами ----- все происходило правильно и в конце в dx было смещение Result'a.
Единственное что, так это я незнаю как просмотреть содержимое Result'a. При попытке просмотреть в СodeView выдало сообщение:
"Expresion cannot be evaluated"
Код: Выделить всё
.model small
.stack 100h
.data
Number = 2
Result db ' ','$'
.code
_start:
mov ax,@data
mov ds,ax
[B]mov es,ax[/B]
mov di,offset Result
mov dx,di
mov ax,Number
mov ch,10
div ch
add ah,'0'
xchg al,ah
stosb
mov ah,09h
int 21h
mov ax,4c00h
int 21h
end _start
Размер этой переменной равен 0, по сути ее адрес такой же, как и у первой команды. Задайте фиксированное значение переменной, например" писал(а):Result db ''
Result db 10 dup(?), '$'
Поменяйте
на mov ax, cs" писал(а):mov ax,@data
It's a long way to the top if you wanna rock'n'roll
Зделал как вы говорили:
Вместо Result db '' написал Result db 10 dup(?) ----- в итоге на екран нечего не выводитса всмысле он пуст.
Зделал по коду airyashov все получилось. Но я немогу понять заечм он занес ax в es, ведь es это всего лиш дополнительный регистр и в дальнейшем он нигде неиспользуетса.
Вместо Result db '' написал Result db 10 dup(?) ----- в итоге на екран нечего не выводитса всмысле он пуст.

Зделал по коду airyashov все получилось. Но я немогу понять заечм он занес ax в es, ведь es это всего лиш дополнительный регистр и в дальнейшем он нигде неиспользуетса.