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
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
but will my code work correctly?
Another way is to pass the parameters as an array. You would only pass the address of the first array element.
Gunther
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
Hi,
mov bx,1
mov ah,48
int 21h
mov ptrTo_struc,ax
Looks like you left off an "H" on the 48.
Steve
well, i simply forgot "ret" when was typing message, my bad :biggrin:
Quote from: FORTRANS on July 23, 2014, 03:12:12 AM
Looks like you left off an "H" on the 48.
yeaw, my bad :biggrin:
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?
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