Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
Programming with NASM / Re: Retrieving element from an array
« Last post by Frank Kotler on August 31, 2021, 10:36:25 PM »
Oops! Even more limited than I remember. Thank you, Frederico!

Best,
Frank


22
Programming with NASM / Re: Retrieving element from an array
« Last post by fredericopissarra 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
23
Programming with NASM / Re: Retrieving element from an array
« Last post by Frank Kotler 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

24
Programming with NASM / Re: Retrieving element from an array
« Last post by fredericopissarra 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.
25
Programming with NASM / Re: Retrieving element from an array
« Last post by debs3759 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.

26
Programming with NASM / Retrieving element from an array
« Last post 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

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
27
Example Code / Subleq
« Last post by ALGOL9000 on August 28, 2021, 01:43:26 AM »
Hello,
I have made a very basic Subleq emulator for Win64Bit, somewhat inspired by the Altair8800.
I think it is a decent example of amateur assembler for windows.
Very top row is current address, second row is the current instruction, bottom is the content of above two addresses.
(press h for help)
I linked it with;   golink  /console  user32.dll  kernel32.dll  sblq.obj
Example of accepted syntax(basic program that continually adds 3 to address 1):
0000 0003 0003
0002 0000 0006
0000 0001 0009
0000 0000 0000
28
Programming with NASM / Re: print on windows
« Last post by fredericopissarra on August 27, 2021, 04:32:41 PM »
Now... if you want to allocate memory use VirtualAlloc() and VirtualFree() Win API functions. They are well documented in MSDN. Tip, as you can see the name of the 'stub' library used to call this functions from kernel32.dll are prefixed and suffixed (in 32 bits mode only) differently, accordingly to the mode used: x86-64 use __imp_ prefix only and i386 mode use prefix __imp__ and sufixed with @N, where N is the number of bytes of the arguments, pushed to the stack.

So, to allocate 128 bytes of memory in i386 mode you must do:
Code: [Select]
; allocate 128 bytes
  push 0       ; NULL.
  push 128     ; sizeof of requested block.
  push 0x1000 ; MEM_COMMIT
  push 4   ; PAGE_READWRITE
  call [__imp__VirtualAlloc@16]
  ; EAX has the address of buffer allocated.

  mov [allocaddr],eax    ; save it.

  ; It is prudent to call VirtualLock here.
  push eax
  push 128 ; size
  call [__imp__VirtualLock@8]
  ...
; deallocate buffer
  push [allocaddr]
  push 128 ; size
  call [__imp__VirtualUnlock@8]

  push [allocaddr]
  push 0 ; size (must be 0 to release memory).
  push 0x8000 ; MEM_RELEASE
  call [__imp__VirtualFree@12]
29
Programming with NASM / Re: print on windows
« Last post by fredericopissarra on August 27, 2021, 04:06:14 PM »
If you need to print a string you'll need to pass the size of this string or, at least, use C style strings and put a NULL char at the and to get this size:

Code: [Select]
; Entry RDI - pointer to char
; Exit: EAX, size of string
; Destroys RDI.
strlen_:
  xor  eax,eax
.loop:
  cmp  byte [rdi],0
  je   .exit
  inc  eax
  inc  rdi
  jmp  .loop
.exit:
  ret

; Entry ECX = stdout handle. RDX = pointer to string.
; Destroys RDI, R8 and R9.
printstr:
  sub  rsp,40  ; Win64 calling convetion reserves 32 bytes on stack (will reserve 8 bytes more)
 
  mov rdi,rdx
  call  strlen_
  mov r8d,eax
  mov r9,rsp
  push 0
  call  [__imp_WriteConsoleA]

  add  rsp,40
  ret

Usage:
Code: [Select]
section .data

msg: db 'hello', 0

section .text
...
  ; rcx must have the stdout handle
  lea rdx,[msg]
  call printstr
30
Programming with NASM / Re: print on windows
« Last post by fredericopissarra on August 27, 2021, 03:37:32 PM »
Use console API (not WriteFile). hello_win.asm (Windows x64), hello_win32.asm (Windows x86).
Pages: 1 2 [3] 4 5 ... 10