Невозможно записать в переменную (ASM)

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

leftbr db "("
rightbr db ")"
input db

start:
mov ah,08
int 21h
mov input,al

output:
mov dl,leftbr
mov ah,02
int 21h
mov dl,key
int 21h
mov dl,rightbr
int 21h

exit:
mov ah,4ch
mov al,00
int 21h

Он падает на «входной базе данных», говоря «недопустимый аргумент». Если я изменю его на "input db "" ", то произойдет сбой при "mov input, al", утверждая, что "недопустимые операнды". Я изменил его на следующее, и теперь он работает.

start:
mov ah,08
int 21h
mov [input],al

output:
mov [leftbr], "("
mov [rightbr], ")"
mov dl,[leftbr]
mov ah,02
int 21h
mov dl,[input]
int 21h
mov dl,[rightbr]
int 21h

exit:
mov ah,4ch
mov al,00
int 21h

leftbr db 0
rightbr db 0
input db 0

person Andrew    schedule 05.01.2011    source источник
comment
db указывает, что один или несколько байтов должны быть зарезервированы, поэтому вам нужно что-то, чтобы указать, что это за байт. вы можете использовать число или символ, но вам нужно что-то.   -  person Michael Lowman    schedule 05.01.2011
comment
Хорошо, я этого не знал. Но как насчет другой проблемы? Недопустимый операнд.   -  person Andrew    schedule 05.01.2011
comment
как насчет ввода db 0?   -  person BlackBear    schedule 05.01.2011


Ответы (1)


Строка mov input, al пытается переместить al в значение, определенное строкой input db 0, например. компилятор переводит его в mov 0, al. То, что вы хотите сделать, это переместить al в position «вход», поэтому я думаю (кодирование ASM было для меня некоторое время назад) mov [input], al или mov byte ptr:[input], al будет работать лучше.

Изменить: это то, что отображает для меня "(a)". Запуск CrunchBang Linux/Wine/FASM для Windows.

format MZ
org 0x100

jmp start
leftbr db "(", 0
rightbr db ")"
input db "a"

start:
xor ax,ax
mov ah,08
;int 21h ; commenting this line because wine doesn't seem to like it
;mov [input],al

output:
mov dl,byte [leftbr]
mov ah,02
int 21h
mov ah,02 ; not sure if ah gets modified, probably not
mov dl,[input]
int 21h
mov ah,02
mov dl,[rightbr]
int 21h

exit:
mov ah,4ch
mov al,00
int 21h 
person Bas    schedule 05.01.2011
comment
+1, но вам не нужно преобразовывать ввод в байт, потому что он уже есть. mov [ввод], al должен работать нормально. - person BlackBear; 05.01.2011
comment
Ах я вижу. хотя думаю не повредит :) - person Bas; 05.01.2011
comment
Не работает. Он компилируется, но программа не выполняется должным образом. Он не ждет ввода, а просто выводит несколько случайных символов. - person Andrew; 05.01.2011
comment
@andrew: какой компилятор ты используешь? НАСМ, ФАСМ, ..? Кроме того, вы работаете под WinXP или как-то еще? Очевидно, INT 21h не работает, потому что он должен остановиться и дождаться хотя бы нажатия клавиши... - person Bas; 05.01.2011
comment
Сейчас работает Linux+FASM+wine. Переместите определения leftbr, rightbr и всего остального в конец вашего кода. Если вы сохраните его в начале, FASM скомпилирует его в этом самом месте. Затем виртуальная машина DOS начнет выполнение с адреса leftbr, содержащего значение (, которое транслируется в поддельный ASM-код. Есть ли в этом какой-то смысл? Вы также можете сделать: jmp _skip_data ‹определения данных здесь› _skip_data: - person Bas; 05.01.2011
comment
Я сделал это (переместите данные ближе к концу). Единственное отличие состоит в том, что теперь он ожидает ввода и печатает 3 символа. Проблема в том, что они не те. - person Andrew; 05.01.2011
comment
Теперь я изменил каждую ссылку на переменную в коде на [имя], и теперь он ожидает ввода и печатает x . Что происходит с парантезом? - person Andrew; 05.01.2011
comment
Для меня это не работает с INT 21h/AH=08 (думаю, это проблема вина). Ваше изменение mov dl,leftbr на mov dl, [leftbr] (поскольку вас интересует байт по адресу leftbr, а не адрес самого leftbr. Также для двух других mov dl введите /ключ и правобр. - person Bas; 05.01.2011
comment
Я сделал. Он печатает x вместо x. - person Andrew; 05.01.2011
comment
Добавьте строку org 0x100 в начало файла. По крайней мере, это сработало для меня. Это как-то связано с адресацией. EXE или COM (не помню) загружаются с определенным смещением (в данном случае 0x100). Если вы не укажете это, FASM будет думать, что ваши переменные находятся где-то еще. На самом деле эти переменные загружаются, начиная с 0x100, в то время как ваш код ссылается на них, начиная с 0x0 (поэтому вы добавляете org 0x100). Я давно не программировал ассемблер, это точно... - person Bas; 05.01.2011
comment
Если поставить переменные в конец, то работает без org 0x100. Если я поставлю их в начале, это не сработает (будет отображаться только ( )) даже с org 0x100. - person Andrew; 05.01.2011
comment
Да, конечно, потому что вы сами ставите значение. Представьте себе следующее: FASM считает, что исходным адресом является 0x00, поэтому адрес leftbr становится (например) 0x50. Затем в строке mov [leftbr], ( вы фактически пишете mov [0x50], ( и затем читаете обратно с того же самого адреса. Вы должны иметь возможность определять свои данные без активного ввода данных, поэтому поставьте org 0x100 и leftbr db (, пропустите mov [leftbr], (. - person Bas; 05.01.2011
comment
Я пробовал это, тот же результат ( ). Не просит ввода. В начале кода стоит org 0x100, переменные с соответствующей им инициализацией ( ( и ) ) и везде одинаковые [] . - person Andrew; 05.01.2011