News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

passing parameters from code

Started by ghjjkl, July 22, 2014, 10:44:08 PM

Previous topic - Next topic

ghjjkl

lets assume we need to pass many many parameters. We need to send these parameters to fill some STRUC. Is following variant right?



_struc STRUC
d dw 0
f dw 0
g dw 0
(many many others)
_struc ENDS


.data
param1 dw 100

(...)

param2 dw 200

(...)

param3 dw 500

(many many others)

(...)

ptrTo_struc dw 0

.code

sub_ proc

  push bp
  mov bp,sp
  mov si,[bp+2]
  xor di,di
  mov es,ax
  mov ax,cs
  mov ds,ax
 
  rep movsw
  mov [bp+2],si
  pop bp

sub_ endp


(...)

mov bx,1
mov ah,48
int 21h
mov ptrTo_struc,ax

(...)


mov di,offset @label
mov ax,cs
mov es,ax

mov ax,param1
stosw
mov ax,param2
stosw
mov ax,param3
stosw
(many many others)

(...)

mov cx,NUMBER_OF_PARAMS
mov ax,ptrTo_struc

push ds

call _sub
@label:
dw 0
dw 0
dw 0

pop ds


dedndave

this creates a new data type, which is a structure
most of the time, we would not define them with 0's - we would use ?, as uninitialized
but, you can create initialized structures, as well
_struc STRUC
d dw 0
f dw 0
g dw 0
;(many many others)
_struc ENDS


now, you want to define the actual data
because you have initialzed them in the structure, you cannot use the .DATA? section
        .DATA
mystruc _struc <>

now, "mystruc" gives you an address you can pass to a routine for processing

ghjjkl

but will my code work correctly?

Gunther

Another way is to pass the parameters as an array. You would only pass the address of the first array element.

Gunther
You have to know the facts before you can distort them.

dedndave

Quote from: ghjjkl on July 22, 2014, 11:47:32 PM
but will my code work correctly?

the simple answer is no
well - you haven't shown us all the code
but, from what i see, it won't work
push ds

call _sub
@label:
dw 0
dw 0
dw 0

pop ds

for lack of a better term, that's crazy code   :biggrin:
i have seen compilers of old pass and/or return data this way
but, to make it work, the first thing your _sub needs to do is to POP the RETurn address off the stack
and - that is the address of the 3 data words
when _sub exits, it has to adjust that address (by 6 in this case) and JMP to the POP DS instruction

that's all well and good, but there are simpler ways to do it

1) define the structure (data type)
2) declare the structure, normally in the data segment
3) pass the address of the structure to the subroutine
there are a few ways to do this
one way is to PUSH the address onto the stack
another way is to simply pass it in a register
4) in the subroutine, access the structure via the passed address
you can read and/or write to the structure members
5) exit the subroutine
if the address was passed on the stack, use RET 2 to "return and pop 2 bytes", discarding the passed address

FORTRANS

Hi,

mov bx,1
mov ah,48
int 21h
mov ptrTo_struc,ax


   Looks like you left off an "H" on the 48.

Steve

ghjjkl

well, i simply forgot "ret" when was typing message, my bad   :biggrin:

ghjjkl


MichaelW

Quote from: ghjjkl on July 22, 2014, 11:47:32 PM
but will my code work correctly?

A better question is, why code it that way when can readily pass "many, many" parameters with simple, straightforward code?
Well Microsoft, here's another nice mess you've gotten us into.

ghjjkl

Quote from: MichaelW on July 23, 2014, 09:28:36 AM
Quote from: ghjjkl on July 22, 2014, 11:47:32 PM
but will my code work correctly?

A better question is, why code it that way when can readily pass "many, many" parameters with simple, straightforward code?
actually i won't use that code i posted. I just considered situation:

if i have function which needs many parameters, to pass they by stack would demand too much memory

So,
#1


sub_ proc

  push bp
  mov bp,sp
  mov si,[bp+2]
  mov ax,cs
  mov ds,ax
 
  (many actions with many parameters)

  mov [bp+2],SOME_ADDRESS
  pop bp
  ret


sub_ endp

(...)

call sub_
dw 0
dw 0
dw 0
dw 0
dw *SOMETHING ELSE*
(so on)


would be better than next code,especially if we have to use stosX movsX lodsX
#2


sub_ proc near c ;many parameters

(many actions with many parameters)

ret

sub_ endp


(...)

invoke sub,12,34,676,87,...,


because we would have many

mov ax,paramN
push ax
mov ax,param(N-1)
push ax
...

following #2