Author Topic: Retrieving element from an array  (Read 14671 times)

Offline tysonprogrammer

  • Jr. Member
  • *
  • Posts: 22
  • Country: us
  • C# application developer attempting assembly.
Retrieving element from an array
« 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

Code: [Select]
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
Code: [Select]
movzx ax, [si + COLS * [row] + [col]]
and it didn't, I tried to put col and row into al and ah and use
Code: [Select]
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
Code: [Select]
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

Code: [Select]
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

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Retrieving element from an array
« Reply #1 on: August 30, 2021, 08:07:09 AM »
To do

movzx ax, [si + COLS * [row] + [col]]

you would need

Code: [Select]
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.

My graphics card database: www.gpuzoo.com

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Retrieving element from an array
« Reply #2 on: August 30, 2021, 10:40:28 AM »
To do

movzx ax, [si + COLS * [row] + [col]]

you would need

Code: [Select]
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:

Code: [Select]
  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

Code: [Select]
  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??):
Code: [Select]
  ; 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.
« Last Edit: August 30, 2021, 10:56:26 AM by fredericopissarra »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Retrieving element from an array
« Reply #3 on: August 30, 2021, 10:38:46 PM »
Hi Tyson,

I see:

Code: [Select]
     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.
Code: [Select]
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


Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Retrieving element from an array
« Reply #4 on: August 31, 2021, 07:22:24 AM »
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: [Select]
  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]

Code: [Select]
$ 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
« Last Edit: August 31, 2021, 07:24:37 AM by fredericopissarra »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Retrieving element from an array
« Reply #5 on: August 31, 2021, 10:36:25 PM »
Oops! Even more limited than I remember. Thank you, Frederico!

Best,
Frank



Offline tysonprogrammer

  • Jr. Member
  • *
  • Posts: 22
  • Country: us
  • C# application developer attempting assembly.
Re: Retrieving element from an array
« Reply #6 on: September 01, 2021, 09:58:52 PM »
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