I want to make a program that takes 10 characters from the user and saves them in a vector DATA, but I get the error
can't add relative quantities
in mov byte ptr DATA[pos], al
when I try to store the value.
How to solve this error?
.model small
.stack 100h
.data
DATA db 10 dup(?)
cont db 010h
pos db 0h
msg db 10,13,7, 'Input: ', '$'
.code
mov ax, @data
mov ds, ax
mov es, ax
mov ah, 09h
lea dx, msg
int 21h
cicle:
mov ah, 01h
int 21h
mov byte ptr DATA[pos], al ;Save ASCII char in position pos in DATA
inc pos
dec cont
jnz cicle
x86 doesn't have memory-indirect addressing modes that can load an index from memory. Keep your index in a register like a normal person, that's what registers are for.
Or use a pointer increment and compare against an end-pointer.
You don't need static storage for cont
either. It's an assemble-time constant which you've chosen to hard-code as 10h
, i.e. 16, which is larger than the amount of space you reserved for DATA... So that's just a bug which goes away if we simply put a label after DATA, or let the assembler calculate its size.
Comparing a register against a label uses the address as an immediate, not loading a value from memory.
.model small
.stack 100h
.data
DATA db 10 dup(?)
DATA_END:
data_size = $ - DATA ; or if you want the size in bytes, you can do this
msg db 10,13,7, 'Input: ', '$'
.code
mov ax, @data
mov ds, ax
mov es, ax
mov ah, 09h
mov dx, OFFSET msg ; There's no reason to use LEA for putting static addresses into registers, except with x86-64 RIP-relative addressing. MOV is shorter and more efficient.
int 21h
mov di, OFFSET DATA
mov ah, 01h ; we can hoist this out of the loop because we don't destroy AH
cicle: ; do {
int 21h
mov [di], al ;Save ASCII char into DATA
inc di
cmp di, OFFSET DATA_END
jb cicle ; }while(p < end_pointer);