Author Topic: using structures as parameters in functions, with NASM and nagoa+.inc  (Read 7190 times)

Offline bibekdahal_bd16

  • Jr. Member
  • *
  • Posts: 2
How do I use structures as function's parameters ? I am using macros from nagoa+.inc.

I wrote the following code to test.

Code: [Select]
%include "nagoa+.inc"

extern MessageBoxA
extern ExitProcess

segment .data USE32
title db "hello", 0
message db "hello world", 0

STRUC MYWORLD_Type
.K RESQ 1
.C RESD 1
.D RESD 1
ENDSTRUC

KALO ISTRUC MYWORLD_Type

IEND

segment .code USE32
global START
START:
PUSH dword[message]
POP dword[KALO+MYWORLD_Type.C]

loccall Hi, [KALO], title
invoke ExitProcess, 0

PROC Hi, mssage, ttle
invoke MessageBoxA, 0, [@mssage+MYWORLD_Type.C], [@ttle], MB_OK
ENDPROC

And I got a message box:


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Well, at least you got a MessageBox! That's a start. I'm at a bit of a disadvantage, in that I don't remember much of what nagoa+.inc does (if I ever knew). In particular, I don't know what '@' does. Maybe I don't need to know...

To start (pun) with...

Code: [Select]
START:
PUSH dword[message]
POP dword[KALO+MYWORLD_Type.C]

You're pushing the "[contents]" of message - the 4 letters "hell" (another pun! :) ). This is being used as an address. In Linux, it would probably segfault. I'm surprised it doesn't GPF or "access violation" in Windows. It may be "by luck" that you're even getting that "garbage string". You want the address of message - without the "[]".

Since what you want to do is not a "memory-to-memory" move, you don't have to use the push/pop method. It would still work, but:

Code: [Select]
mov dword [KALO + MYWORLD_Type.c], message

should do it. That might be enough to fix the problem - may depend on what "@" does. You may need to "dereference" it. Lemme see...

Code: [Select]
loccall Hi, [KALO], title
invoke ExitProcess, 0

PROC Hi, mssage, ttle
invoke MessageBoxA, 0, [@mssage+MYWORLD_Type.C], [@ttle], MB_OK

You call "Hi" with "[KALO] as a parameter. Per the question in the topic, it would be possible to copy the entire contents of the structure to the stack, but generally you'd want to use the address of the structure as a parameter...

Code: [Select]
loccall Hi, KALO, title
invoke ExitProcess, 0

PROC Hi, mssage, ttle
mov eax, [@mssage]
mov eax, [eax + MYWORLD_Type.C]
invoke MessageBoxA, 0, eax, [@ttle], MB_OK
ENDPROC

I won't guarantee it, but I think that'll work. Another way might be to call "Hi" with the actual message (the address of "message", that is).

Code: [Select]
loccall Hi, KALO + MYWORLD_Type.C, title
invoke ExitProcess, 0

PROC Hi, mssage, ttle
invoke MessageBoxA, 0, [@mssage], [@ttle], MB_OK

Since you mention using a structure as a parameter, that may not be what you want to do, but it would "make more sense" in a way. If you had named the second parameter to your PROC "pointer_to_structure_containing_message" instead of "mssage", it might be more clear that you want to do it the first way. It "makes more sense" to me to do it the second way, but if it "makes more sense" to you to do it the first way, well... you're the programmer!

I'm ASSuming that "@mssage" expands to "ebp + 12". As I recall, NaGoA will also do it without a stack frame, in which case it would be "esp + 8" - should refer to the same memory in either case. If I'm wrong on this, all bets are off!

The best feature of Nasm's macro system is that everybody can write their own macros. The worst feature is that everybody does! :) This can result in a "Tower of Babel" situation. The NaGoA macros may not be the same as the NASMX macros which may not be the same as... whatever else is out there. So I may be totally confused, but try one or the other ideas above, and see what it does. If all else fails, I can look at nagoa+.inc and try to figure out what it does for/to us. Good luck!

Best,
Frank


Offline bibekdahal_bd16

  • Jr. Member
  • *
  • Posts: 2
Thnx, it works.
Code: [Select]
%include "nagoa+.inc"

extern MessageBoxA
extern ExitProcess

segment .data USE32
title db "hello", 0
message db "hello world", 0

STRUC MYWORLD_Type
.K RESQ 1
.C RESD 1
.D RESD 1
ENDSTRUC

KALO ISTRUC MYWORLD_Type

IEND

segment .code USE32
global START
START:
mov dword [KALO + MYWORLD_Type.C], message

loccall Hi, KALO, title
invoke ExitProcess, 0

PROC Hi, mssage, ttle

mov eax, [@mssage]

invoke MessageBoxA, 0, [eax + MYWORLD_Type.C], [@ttle], MB_OK

ENDPROC

But how do I assign some string to [@mssage+ MYWORLD_Type.C] from inside the function?



Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Mmmm, well if I'm correct that "@mssage" expands to "ebp + xxx" (or "esp + xxx"), then "[@mssage + MYWORLD_Type.C]" would refer to some memory on the stack - I was mistaken to say that it "should segfault", it's valid memory, but not what you want. After you've done the "mov eax, [@mssage]", then "eax + MYWORLD_Type.C" would be exactly the same as "KALO + MYWORLD_Type.C" outside the function. So "mov [eax + MYWORLD_Type.C], otherstring" should work. If "otherstring" is passed as a parameter to "Hi" (which would be more "reuseable"), then "@otherstring" would also be "some memory on the stack" - "[contents]" of that memory would be the address of your string. Perhaps something like:

Code: [Select]
mov eax, [@mssage]
mov ecx, [@otherstring]
mov [eax + MYWORLD_Type.C], ecx
...

I'm not certain what you're trying to do - why you're using the "struc" - so I may be confused...

Best,
Frank