News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

changing data in function

Started by ghjjkl, June 20, 2014, 06:06:41 PM

Previous topic - Next topic

ghjjkl

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   :(


nidud

#1
deleted

dedndave

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

ghjjkl

um... i understand now, i didn't consider these problems to be the same... so sorry for this topic then and thanks for attention  :(

ghjjkl

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]?

nidud

#5
deleted

ghjjkl

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

nidud

#7
deleted

dedndave

#8
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

ghjjkl

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

dedndave

see if this works...

(see next post)

dedndave

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

ghjjkl

no, sorry, it doesnt work.... should there be "mov [bx].some.a_,5" instead "mov [bx]._some.a_,5"?

dedndave

maybe
    mov     _some[bx].some.a_,5

_some gets you the address
some gets you the structure offsets

ghjjkl

wow, it works! Thanks, finally i got it     :biggrin: