NASM Forum > Programming with NASM
Retrieving element from an array
tysonprogrammer:
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
--- Code: ---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
--- End code ---
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
--- Code: ---movzx ax, [si + COLS * [row] + [col]]
--- End code ---
and it didn't, I tried to put col and row into al and ah and use
--- Code: ---movzx ax, [si + COLS * al + ah]
--- End code ---
but that didn't work either
The only way I could get it to work was use use literal numbers
--- Code: ---moves ax, [si + 5 * 1 + 1]
--- End code ---
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
--- Code: ---nasm -f bin -o array.com array.asm
--- End code ---
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
debs3759:
To do
movzx ax, [si + COLS * [row] + [col]]
you would need
--- Code: ---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]
--- End code ---
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.
fredericopissarra:
--- Quote from: debs3759 on August 30, 2021, 08:07:09 AM ---To do
movzx ax, [si + COLS * [row] + [col]]
you would need
--- Code: ---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]
--- End code ---
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.
--- End quote ---
Assuming the code is for real mode:
--- Code: --- 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]
--- End code ---
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
--- Code: --- mov al,[si + ax] ; this doesn't exist!
--- End code ---
If the code is intended to 386+, using movzx is allowed ONLY if the registers are extended (E??):
--- Code: --- ; 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
--- End code ---
Of course, this code don't deal with data crossing a segment boundary.
Frank Kotler:
Hi Tyson,
I see:
--- Code: --- mov di, [numbers]
--- End code ---
This will move the first couple of bytes of your variable (zeros) into di. You almost certainly want the address of the variable.
--- Code: ---mov di, numbers
--- End code ---
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
fredericopissarra:
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.
--- Code: --- 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]
--- End code ---
--- Code: ---$ 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
--- End code ---
Navigation
[0] Message Index
[#] Next page
Go to full version