Консультация № 177764
09.04.2010, 03:31
0.00 руб.
0 11 2
Добрый день! Вопрос о модификации адресов. Почему запись
mov ax,120h
mov [bx],ax
правильна, а просто одна команда mov [bx],120h (без предыдущей команды mov ax,120h) неправильна и пишется invalid instruction operands? Однако, если заменить mov [bx],120h на mov word ptr [bx],120h, то всё компилируется. Какую роль играет именно здесь word ptr, зачем он тут нужен? Регистр bx двубайтный, число 120h тоже двубайтное, всё же согласовано, для чего переопределять? Если бы число было от 0 до 0FFh, т.е. однобайтным, тогда переопределение было бы уместным. Или процессор полагает, что вдруг я хочу занести один байт из 120h вместо двух и выдаёт своего рода предупреждение и требует уточнения? Но тогда почему mov byte ptr [bx],120h - invalid instruction operands, а mov byte ptr+1 [bx],120h вообще constant expected? Заранее спасибо.

Обсуждение

Неизвестный
09.04.2010, 04:33
общий
11.04.2010, 02:01
это ответ
для генерации кода команды компилятору необходимо четко знать размер операнда

в данном случае мы имеем дело с косвенной адресацией, т.е. адрес операнда содержится в регистре
mov [bx],ax - поместить значение регистра AX по адресу, который содержится в регистре BX
здесь размер операнда известен (разрядность AX = 16 бит), поэтому будет сгенерирована команда для записи слова


рассмотрим такой пример:
1) mov byte ptr [bx],1
2) mov word ptr [bx],1

эти две команды похожи, но имеют разный код
это разные команды
первая строка - "записать байт со значением 1 по адресу, который содержится в регистре BX"
вторая строка - "записать слово со значением 1 по адресу, который содержится в регистре BX"

если в роли операнда мы указываем константу, то необходимо явно задавать размер данных
в случае mov [bx],ax неявно подразумевается mov word ptr [bx],ax
mov [bx],ax = mov word ptr [bx],ax


смотрим дальше
mov byte ptr [bx],120h
дело в том, что 120h = 288 = 100100000b
не влезает такое большое значение в 1 байт (8 бит), вот беда какая
максимальное значение байта равно FFh = 255 = 11111111b
а вот mov word ptr [bx],120h компилируется без ошибок, 255 в шестнадцати битах уместится без проблем
4
давно
Посетитель
7438
7205
09.04.2010, 12:52
общий
это ответ
Здравствуйте, Adsorores.
Хоть уважаемые мной эксперты и поддержали ответ эксперта Alex_S, мне кажется, что на вопрос все-таки не был дан ответ...
Сказано то, с чем автор вопроса и так согласен ...

Так понял, речь идет о masm-е. Именно он выдает такую ошибку. Видать, это ошибка самого masm-а.
Та же ошибка будет, если дать операндом байт! Т.е. masm в обоих случаях считает неопределенной разрядность операнда. Что неверно.
Чтобы не было ошибки, надо явно указывать разрядность word ptr или byte ptr.

А mov byte ptr+1 [bx],20h - просто ошибка, после byte ptr нельзя писать +1
Но можно записать mov byte ptr 1[bx],20h

Кстати, tasm команду mov [bx],120h обрабатывает корректно и никаких сообщений не выводит.
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
10.04.2010, 13:44
общий
Alex_S, спасибо за ответ!
Лысков Игорь Витальевич, совершенно в точку! Интересовал вопрос уместности
word ptr для двубайтного регистра и только для двубайтного числа. Тем более что в одном уважаемом учебнике по ассемблеру в главе "Косвенные ссылки" автор разбирал тему на примере mov [bx],300, который у меня без word ptr ну никак не хотел комплироваться. Я вообще фигел, то ли у автора опечатка, то ли я такой тупой. Дело оказалось в моём компиляторе MASM611. Большое спасибо!
Неизвестный
15.04.2010, 18:42
общий
Поздно увидел этот вопрос. Хотел заметить, что такое поведение masm'a, скорее, более правильное, чем у того же tasm'а. Т.к. в выражении
mov [bx], 120h
размерность действительно неопределенная. Дело в том, что 120h > 0FFh (байт), но меньше 0FFFFh (два байта) и тем более 0FFFFFFFFh (четыре байта). А это значит, что размерность 120h может быть и WORD и DWORD. В результате может возникнуть неявная ошибка, когда программист хотел использовать одну размерность, а получил другую (tasm).
Даже если учесть, что явно не указан 32-битный процессор директивой .386 и пр., то отсутствие этой директивы не является основанием для компилятора интерпретировать неоднозначности каким-либо способом. Вполне возможна такая ситуация, когда программа скомпилируется без ошибок, будет работать, но неправильно, а программист узнает о том, что забыл .386 директиву, слишком поздно, если вообще узнает об этом.
давно
Посетитель
7438
7205
16.04.2010, 00:13
общий
Xaud:
Я не согласен с Вами. Должен заметить, что для 16-битного ассемблера основной размерностью является word. Поэтому вполне закономерно считать разрядностью по-умолчанию - 16, при этом никакой неопределенности! И ожидать 32 бита нет резона. Если указать .386, вот тогда будет неопределенность.
К тому же, директива .386 указывается только, если действительно нужны 32-битные возможности, не так ли?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
16.04.2010, 09:36
общий
Кстати, "о птичках" , Вы пробывали в программе без указания .386 скомпилировать команду mov dword ptr [bx], 1234h ?
Попробуйте и увидете, что компилятор думает по этому поводу
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
16.04.2010, 09:37
общий
Xaud:
Простите, не указал адресата... Посмотрите пост чуть выше...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
16.04.2010, 20:22
общий
Лысков Игорь Витальевич:
В изначальном вопросе не было ограничений на размерность данных , размерность адреса, безусловно, 16 бит. Была лишь показана часть кода, вызывающая сомнения. Конечно, если указать .386, то размерность данных будет до 32 бит, но ведь в своем сообщении я и говорил про случай, когда директива 32 битной поддержки не указана (либо программист забыл, либо действительно не нужна), и появлялась неопределенность (однозначно о размере константы ничего сказать нельзя), которая интерпретировалась tasm'ом по своему усмотрению.

Кстати, "о птичках" , Вы пробывали в программе без указания .386 скомпилировать команду mov dword ptr [bx], 1234h ?
Попробуйте и увидете, что компилятор думает по этому поводу


Я, собственно, про это и говорил, что если бы программисту приходилось явно указывать размерность, как в вашем примере, то он бы сразу "словил" бы ошибку трансляции, если бы забыл .386 (и иже с ними), а без указания размерности ошибка может "уйти в подполье" -- т.е. быть не явной .



давно
Посетитель
7438
7205
16.04.2010, 23:33
общий
Xaud:
По-моему, все таки ситация надуманная...
Тяжело представить, когда от возможностей 386 требуется только иметь возможность использовать mov dword ptr [bx], 1234h и при этом забыть написать .386...
Обычно, или используется весь арсенал 386-го, либо не используется ничего.
В конце концов, каждый выбирает тот инструмент, который ему нравится Кому-то может больше по душе FASM...
Так что все эти разговоры на тему "вкуса и цвета" смысла не имеют... У каждого свой взгляд на достоинства и недостатки. Так что, "мир, труд, жвачка"!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
17.04.2010, 15:02
общий
Я не соглашусь с вами. В моей практике было несколько подобных случаев. В частности, например, весь код сплошь 16-битный, а необходимы были некотрые манипуляции с 32-х битными данными. Компиляция -- ок, программа работет, но не так, как надо ...
Поэтому "либо все 32, либо ничего из 32" не всегда срабатывает ...
Я не сторонник игнорировать каки-либо инструменты -- пользуюсь различными компиляторами с учетом их "плюсов" и "минусов".
К чему это я всё пишу, да к тому, что хотел обратить внимание пишущих программы по возможности избегать ситуаций с неоднозначной интерпретацией. Не нужно надеяться на компилятор и давать ему волю в принятии решения -- он сделает выбор, но не всегда логичный и правильный с точки зрения рограммиста .
[offtop]
Пользуясь случаем, пооффтоплю:
Хочу выразить благодарнось создателям и поддерживающим данный ресурс: молодцы ребята! Продолжайте в том же духе!
[/offtop]

давно
Посетитель
7438
7205
19.04.2010, 04:44
общий
Xaud:
Я не сторонник игнорировать каки-либо инструменты -- пользуюсь различными компиляторами с учетом их "плюсов" и "минусов"
Я тоже.
Не нужно надеяться на компилятор и давать ему волю в принятии решения -- он сделает выбор, но не всегда логичный и правильный с точки зрения программиста
И с этим согласен. Я просто считаю, что программист на ассемблере должен, просто обязан, все держать под контролем. Лично я начинаю отлаживать программу после добавления каждой "пары строк", чтобы убедиться, правильно ли идет процесс. Если начинать отлаживать, когда практически все написано, то, действительно, можно некоторые моменты упустить.
И все же, в данном конкретном случае, я считаю, что для 16-битной программы стандартными должны считаться именно 16-битные данные, если нужно другое, то надо об этом побеспокоиться.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа