MASM: как устранить недопустимый немедленный режим в программировании 8086?

avatar
Ankur
16 октября 2020 в 15:11
1193
1
2

Я решаю фундаментальный вопрос программирования на языке ассемблера, чтобы добавить числа BCD и два числа ASCII, для этого я понял, что мне нужно использовать инструкции DAA и AAA соответственно. Теперь я пытаюсь сохранить результат, хранящийся в регистре AX, в нужное место в памяти, но не понимаю, почему следующий код дает мне ошибка Немедленный режим недопустим Ниже приведен код, который я кодировал до сих пор, пожалуйста, помогите мне, как устранить эту ошибку. PS: я хочу переместить свой результат в требуемую ячейку памяти, а не в какой-либо регистр специального назначения

ASSUME CS:CODE,DS:DATA
DATA SEGMENT
DATA ENDS
CODE SEGMENT
START:
 MOV AX,0000H
 MOV DS,AX
 MOV AL,59
 MOV BL,35
 ADD AL,BL
 DAA
 MOV CX,0000
 MOV ES,CX
 MOV [0000],AX
 MOV AL,04
 MOV BL,05
 ADD AL,BL
 AAA
 MOV CX,0000
 MOV ES,CX
 MOV [0010],AX
 MOV AH,04CH
 INT 21H
CODE ENDS
END START
Источник
Ankur
16 октября 2020 в 15:44
0

Спасибо за ответ, на самом деле я хочу переместить результат в любое случайное место, поэтому я хочу сохранить его в 0000: 0000 и 0000: 0010 @MichaelPetch

Ankur
16 октября 2020 в 15:54
0

Спасибо, пожалуйста, напишите свой ответ

Ankur
16 октября 2020 в 15:59
0

Теперь я научился у вас, большое спасибо, сэр.

Ответы (1)

avatar
Michael Petch
16 октября 2020 в 18:40
6

Вы столкнулись с особенностью синтаксиса MASM. Если у вас есть операнд памяти только с непосредственным значением, которое не является меткой (например, [0000] или [0010]), MASM выдаст ошибку Immediate mode Illegal. На самом деле в такой инструкции нет ничего плохого, но MASM имеет для нее особый синтаксис. Вы должны явно указать сегментный регистр. Многие ассемблеры предполагают DS для этого случая, но MASM этого не делает.

Чтобы обойти эту проблему, используйте следующий синтаксис:

MOV [DS:0000],AX
MOV [DS:0010],AX

MASM также позволяет:

MOV DS:[0000],AX
MOV DS:[0010],AX

Первый вариант предпочтительнее, так как TASM (совместимый с MASM ассемблер) не поддерживает последний вариант. Если вы поместите сегмент внутрь, он должен работать с ассемблером MASM и TASM, а также с ассемблером JWASM с открытым исходным кодом.

Если ваш операнд памяти включает регистр и смещение, то MASM не будет жаловаться, так что это допустимый синтаксис MASM:

MOV [BX+0000],AX
MOV [BX+0010],AX

Если вы хотите переместить непосредственное значение (источник) в адрес памяти, который является просто непосредственной ссылкой, тогда синтаксис выглядит следующим образом:

MOV WORD PTR [DS:0000], 0100h
MOV BYTE PTR [DS:0000], 00h

Следует отметить, что значение 0010 представляет собой десятичное число 10 (не HEX). Неясно, хотели ли вы использовать десятичный или шестнадцатеричный код в своем коде. Шестнадцатеричные значения имеют суффикс H.


Примечание: я сделал комментарий об обнулении сегментного регистра, который теперь удален. Хотя мой комментарий был правильным, я не присмотрелся достаточно близко, чтобы понять, что вы установили DS на 0000, поэтому ваш код обращается к 0000: 0000 и 0000: 0010. В этом отношении ваш код правильный, хотя неясно, почему вы изменяете эту часть памяти. В системе, совместимой с IBM-PC, таблица векторов прерываний (IVT) находится в первых 1024 байтах памяти. Вы можете работать в системе, не совместимой с IBM-PC, и то, что вы делаете, может вообще не вызывать проблем. Я просто хотел предупредить вас об этом.

Peter Cordes
16 октября 2020 в 21:16
3

Ответ Росса на Запутанные скобки в MASM32 показывает примеры того, как MASM в основном игнорирует [], когда внутри них нет регистра.