The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: ghjjkl on June 20, 2014, 06:06:41 PM

Title: changing data in function
Post by: ghjjkl on June 20, 2014, 06:06:41 PM
Hello again, i have some new novice's problem: how to pass address of some data to change it in function? I tried something like "invoke func,offset _address" and then, for example, in function: "mov ax, word ptr @data:[_address_which's_argument]", but it doesnt work, and ax contains yet another value i can't recognize   :(

Title: Re: changing data in function
Post by: nidud on June 20, 2014, 07:27:42 PM
deleted
Title: Re: changing data in function
Post by: dedndave on June 20, 2014, 07:34:59 PM
i have to admit that i have never tried INVOKE in 16-bit code, but there's no reason it shouldn't work
that's because, in DOS days, i used MASM v 5.1 which did not support INVOKE

INVOKE'd functions require a PROTOtype, generally placed early in the file
(well - they require one if the INVOKE is to appear before the PROC)
the prototype tells the assembler how many arguments to expect, and their sizes
it may also tell the assembler which type of calling convention to use and the distance (NEAR or FAR)
for 32-bit programs, everything is NEAR, and the default is StdCall (defined in the .MODEL directive)
i am not sure how that works in 16-bit code
you'll have to consult the MASM manual for details

MyFunc  PROTO  <dist> <type> :WORD,:WORD,:WORD
<dist> would be replaced with NEAR or FAR
<type> would be C, Pascal, Basic, StdCall, SysCall, etc
the default depends on the .MODEL and OPTION's (read the manual)
let's assume you use NEAR and StdCall.....

then, in the code section...
        .CODE

        INVOKE  MyFunc,arg1,arg2,arg3


and, the function

MyFunc PROC  NEAR StdCall _arg1:WORD,_arg2:WORD,_arg3:WORD

        mov     ax,_arg1
        mov     cx,_arg2
        mov     dx,_arg3
;
;
        ret

MyFunc ENDP


because you use NEAR and StdCall, the actual code generated might look like this
        push    arg3
        push    arg2
        push    arg1
        call    MyFunc


and....

MyFunc:
        push    bp
        mov     bp,sp

        mov     ax,[bp+4]
        mov     cx,[bp+6]
        mov     dx,[bp+8]
;
;
        leave
        ret     6


the LEAVE instruction is essentially the same as
        mov     sp,bp
        pop     bp


RET 6 returns and POP's 6 bytes off the stack (the passed arguments)

the behaviour is different for other <dist> and <type> parameters
Title: Re: changing data in function
Post by: ghjjkl on June 20, 2014, 07:40:21 PM
um... i understand now, i didn't consider these problems to be the same... so sorry for this topic then and thanks for attention  :(
Title: Re: changing data in function
Post by: ghjjkl on June 20, 2014, 08:21:46 PM
and what if i'll want to pass STRUC's address in function? Should i consider its members as [bx+number_of_bytes_before_some_member]?
Title: Re: changing data in function
Post by: nidud on June 20, 2014, 08:43:09 PM
deleted
Title: Re: changing data in function
Post by: ghjjkl on June 20, 2014, 09:10:41 PM
wow, that's cool  :t
what does "assume " mean with registers like bx? I used "assume" with registers like ds,cs,ss,es so far
Title: Re: changing data in function
Post by: nidud on June 20, 2014, 10:02:26 PM
deleted
Title: Re: changing data in function
Post by: dedndave on June 20, 2014, 10:35:52 PM
normally, we would pass the address of the entire structure
        INVOKE  MyFunc,offset S

then, in the routine, address the individual member(s)
you can use ASSUME, as nidud mentioned - but you don't have to
MyFunc PROC pStruct:WORD

        mov     bx,pStruct
        mov     al,[bx].S1.m1
        mov     cx,[bx].S1.m2


you could also pass the address of an individual member
        INVOKE  MyFunc,offset S.m2
Title: Re: changing data in function
Post by: ghjjkl on June 22, 2014, 03:06:17 AM
But what about arrays of STRUC's? If i want to change some members, using cycle,i could try:

some struc
a_ dw ?
b_ dw ?
some ends

.data

_some some 10 dup (<0,0>)

.code

mov ax,@data
mov ds,ax

xor bx,bx
.while bx<10
mov _some[bx].a_,5
inc bx
.endw

but it doesnt work.
Well, should i try this?

some struc
a_ dw ?
b_ dw ?
some ends

.data

_some some 10 dup (<0,0>)

.code

mov ax,@data
mov ds,ax

xor bx,bx
mov ax,10
cwd
mov dx,sizeof some
mul dx
.while bx<ax
mov _some[bx].a_,5
add bx,sizeof some
.endw
Title: Re: changing data in function
Post by: dedndave on June 22, 2014, 03:16:17 AM
see if this works...

(see next post)
Title: Re: changing data in function
Post by: dedndave on June 22, 2014, 03:21:11 AM
nix that one
try this

some struc
a_ dw ?
b_ dw ?
some ends

.data

_some some 10 dup (<0,0>)

.code

mov ax,@data
mov ds,ax

xor bx,bx
.while bx<(10*sizeof some)
mov [bx]._some.a_,5
add bx,sizeof some
.endw
Title: Re: changing data in function
Post by: ghjjkl on June 22, 2014, 04:12:28 AM
no, sorry, it doesnt work.... should there be "mov [bx].some.a_,5" instead "mov [bx]._some.a_,5"?
Title: Re: changing data in function
Post by: dedndave on June 22, 2014, 05:42:04 AM
maybe
    mov     _some[bx].some.a_,5

_some gets you the address
some gets you the structure offsets
Title: Re: changing data in function
Post by: ghjjkl on June 22, 2014, 04:23:31 PM
wow, it works! Thanks, finally i got it     :biggrin: