NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: tysonprogrammer on August 29, 2021, 11:26:20 PM
-
Hello
I am trying to learn how to access an array element. Setting elements in't that hard to getting the value back out is.
here is what I have
org 100h
section .data
numbers db 0,0,0,0,0
db 0,0,0,0,0
db 0,0,0,0,0
COLS EQU 5
section .text
mov di, [numbers]
mov [di], byte1
mov [di+4+1], byte 2
mov [di+4_2+2], BYTE 3
push numbers
push 1
push 1
call get_element
jmp exit
get_element:
%define col bp+4
%define row bp+6
%define array db+8
push bp
mov db, sp
mov di, [array]
add si, [col]
mov bx, COLS
mov ax, [row]
mul bx
; here is where I think the issue is
movzx, [si + ax]
pop bp
ret 10
exit:
mov ah 04ch
mov al, 0
int 21h
I have tried may ways to get around the invalid effective address error
The one I would like to use is something like this which I know won't work movzx ax, [si + COLS * [row] + [col]]
and it didn't, I tried to put col and row into al and ah and use
movzx ax, [si + COLS * al + ah]
but that didn't work either
The only way I could get it to work was use use literal numbers
moves ax, [si + 5 * 1 + 1]
But that doesn't really allow me to use a routine to get the element value
I use the following coammdn to compile the program
nasm -f bin -o array.com array.asm
How do I get a value from an array using a routine and passed in values?
by the way I type this in all by hand so there maybe some code issues, I am not able to copy and paste right now from the virtual machine.
thanks,
Tyson
-
To do
movzx ax, [si + COLS * [row] + [col]]
you would need
mov al,COLS
mul byte [row]
add al,[col] ; this assumes that the entire array will never be more than 256 bytes
mov al, [si + ax]
This assume columns and rows fit into a byte. The mul clears ah if the entire array is no more than 256 bytes, so you don't need movzx.
-
To do
movzx ax, [si + COLS * [row] + [col]]
you would need
mov al,COLS
mul byte [row]
add al,[col] ; this assumes that the entire array will never be more than 256 bytes
mov al, [si + ax]
This assume columns and rows fit into a byte. The mul clears ah if the entire array is no more than 256 bytes, so you don't need movzx.
Assuming the code is for real mode:
mov al,COLS
mul byte [row] ; AX = [row] * COLS
xor bx,bx
mov bl,[col] ; BX = [col]
add bx,ax
mov al,byte [bx + si]
Notice: if multiplying row by COLS you get something greater than 255, AH != 0, so the base address (BX) must be 16 bits too. And [si + ax] isn't valid in real mode effective address (the base address must be in BX or BP and index in SI or DI only!). So
mov al,[si + ax] ; this doesn't exist!
If the code is intended to 386+, using movzx is allowed ONLY if the registers are extended (E??):
; This works on real mode (386+).
mov al,COLS
mul byte [row]
movzx eax,ax
movzx edx,byte [col]
add eax,edx
mov al,[esi + eax] ; This is OK
Of course, this code don't deal with data crossing a segment boundary.
-
Hi Tyson,
I see:
mov di, [numbers]
This will move the first couple of bytes of your variable (zeros) into di. You almost certainly want the address of the variable.
mov di, numbers
Try that change and see if it goes better.
It has been a long time since I've done 16 bit code, but the addressing modes are quite limited. I think [di + ax] will not work but [di + bx] or [di + si] would...
Good Luck!
Best.
Frank
-
Only BX or BP can be used as base address and only SI or DI can be used as index. If BP is used SS is assumed, otherwise, BX, then DS is assumed.
It is possible use different registers in an effective address only with E?? (and R??) registers.
[bx+di] is valid, but [di+si] isn't.
mov al,[bx] ; ok
mov al,[si] ; ok
mov al,[di] ; ok
mov al,[bp] ; ok
mov al,[bx+si] ; ok
mov al,[bx+di] ; ok
mov al,[bp+si] ; ok
mov al,[bp+di] ; ok
; All invalid
mov al,[ax]
mov al,[cx]
mov al,[dx]
mov al,[sp]
mov al,[ax+bx]
mov al,[ax+cx]
mov al,[ax+dx]
mov al,[ax+si]
mov al,[ax+di]
mov al,[ax+bp]
mov al,[ax+sp]
mov al,[bx+cx]
mov al,[bx+dx]
mov al,[bx+bp]
mov al,[bx+sp]
mov al,[cx+dx]
mov al,[cx+si]
mov al,[cx+di]
mov al,[cx+bp]
mov al,[cx+sp]
mov al,[dx+si]
mov al,[dx+di]
mov al,[dx+bp]
mov al,[dx+sp]
mov al,[si+di]
mov al,[si+sp]
mov al,[di+sp]
mov al,[bp+sp]
$ nasm test.asm
test.asm:10: error: invalid effective address
test.asm:11: error: invalid effective address
test.asm:12: error: invalid effective address
test.asm:13: error: invalid effective address
test.asm:14: error: invalid effective address
test.asm:15: error: invalid effective address
test.asm:16: error: invalid effective address
test.asm:17: error: invalid effective address
test.asm:18: error: invalid effective address
test.asm:19: error: invalid effective address
test.asm:20: error: invalid effective address
test.asm:21: error: invalid effective address
test.asm:22: error: invalid effective address
test.asm:23: error: invalid effective address
test.asm:24: error: invalid effective address
test.asm:25: error: invalid effective address
test.asm:26: error: invalid effective address
test.asm:27: error: invalid effective address
test.asm:28: error: invalid effective address
test.asm:29: error: invalid effective address
test.asm:30: error: invalid effective address
test.asm:31: error: invalid effective address
test.asm:32: error: invalid effective address
test.asm:33: error: invalid effective address
test.asm:34: error: invalid effective address
test.asm:35: error: invalid effective address
test.asm:36: error: invalid effective address
test.asm:37: error: invalid effective address
-
Oops! Even more limited than I remember. Thank you, Frederico!
Best,
Frank
-
Thanks guys for your wisdom. I ended up using bx and it worked like a charm. I knew I was close, I probably could of dug through my masm book to find it but thought this was quicker, and it was. Just took me a few days to respond.
thanks,
Tyson