flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Need added functionality to the invoke's quoted string

Author
Thread Post new topic Reply to topic
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 07 Apr 2006, 16:45
I was wondering if it would be to much trouble to add vanilla text formatting functionality to the invoke macro's quoted string feature (\n, \t, etc.)?
Code:
EX: invoke MessageBox, [hwnd], "How are ya?! \n", "Caption", MB_OK    
Post 07 Apr 2006, 16:45
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 07 Apr 2006, 17:21
Since this is assembly, isn't this better:
Code:
invoke MessageBox, [hwnd], <"How are ya?! ",13,10>, "Caption", MB_OK    
?
Post 07 Apr 2006, 17:21
View user's profile Send private message Visit poster's website Reply with quote
bogdanontanu



Joined: 07 Jan 2004
Posts: 403
Location: Sol. Earth. Europe. Romania. Bucuresti
bogdanontanu 07 Apr 2006, 17:58
IMHO it IS much better.

Like this you can add whatever ASCII code you like and you do not have to remember special notations for CR or LF
Post 07 Apr 2006, 17:58
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 07 Apr 2006, 18:20
Yes, that is much better Smile , I had no idea you could do something like that Surprised . thanks again, Tomasz Razz .
Post 07 Apr 2006, 18:20
View user's profile Send private message Reply with quote
Mark Larson



Joined: 04 Nov 2006
Posts: 13
Mark Larson 08 Nov 2006, 12:50
Tomasz Grysztar wrote:
Since this is assembly, isn't this better:
Code:
invoke MessageBox, [hwnd], <"How are ya?! ",13,10>, "Caption", MB_OK    
?


I am having problems getting that to work with printf(). I just recently converted to fasm yesterday ( I have linux installed), so it's quite possible I am doing something boneheaded. I have the cdecl.inc I got from the distribution I downloaded ( cdecl.inc). I also tried proc32.inc I got from revolution's thread on not using ebp. ( http://board.flatassembler.net/topic.php?t=5938 )

When using the cdecl.inc I get tihs error
Code:
flat assembler  version 1.67.14  (16384 kilobytes memory)
raytrace.asm [213]:
        invoke  printf,<"Micro: %u",10>,eax
error: illegal instruction.
    


( I just realized from the error message that CDECL.INC doesn't have "invoke" in it).


when using prot32.inc from revolution I get this one ( I am not including both)
Code:
flat assembler  version 1.67.14  (16384 kilobytes memory)
raytrace.asm [213]:
        invoke  printf,<"Micro: %u",10>,eax
/home/mark/programming/include/proc32.inc [17] invoke [3]:
     pushd arg
error: value out of range.
    


I am also getting a second problem with nested structures. I looked up nested structures in the manual and did a search for them on the forums. I am getting a compile error from an included include file when I do this:
Code:
struct   point
        x       dd      ?
        y       dd      ?
        z       dd      ?
        d       dd      ?
ends


struc   cShere
        a               point
ends



flat assembler  version 1.67.14  (16384 kilobytes memory)
raytrace.inc [30]:
        a               point
error: unexpected characters.

    


I checked over the code carefully and I can't seem to find a problem with the way I am doing it.

thanks in advance for any help Smile

Mark

_________________
BIOS programmers do it fastest! Wink
Post 08 Nov 2006, 12:50
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 08 Nov 2006, 13:30
For the first problem: you need a "pushd" macro as it is defined by extended Win32 headers (like the INCLUDE/WIN32AX.INC file in fasm for Windows package) to have code-embedded strings working. Also for CDECL you should use "ccall" to call the function directly and maybe "cinvoke" if you want to call the procedure indirectly (through the variable containing address to function).

For the second one: it's because you used STRUC keyword, which the low-level preprocessor's directive that expects the structure block to begin with { character (thus the "a point" is considered "unexpected" by it).
Post 08 Nov 2006, 13:30
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 Nov 2006, 14:36
Mark: these macros are only included in Win32 distribution of FASM. There is no official linux macros, altough some of win distro can be used in linux
Post 08 Nov 2006, 14:36
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Mark Larson



Joined: 04 Nov 2006
Posts: 13
Mark Larson 08 Nov 2006, 20:43
Thanks for the help! I've been using MASM for a really long time, and I have it down pat. So it'll take me a bit to get used to fasm.

I need to be able to do 32-bit/64-bit coding ( I have Ubuntu for both), and had originally gone with yasm. But it didn't support some features I needed such nested structures.

_________________
BIOS programmers do it fastest! Wink
Post 08 Nov 2006, 20:43
View user's profile Send private message Visit poster's website Reply with quote
MichaelH



Joined: 03 May 2005
Posts: 402
MichaelH 08 Nov 2006, 22:53
Hi folks, this is a neat trick but can someone please explain exactly what's happening in the expanded code. I have extracted all the if/else code to reveal what will be output to file.

Code:

                                                        ;invoke MessageBox, 0, <"How are ya?! ",13,10>, "Caption", 0
                                                
0000020A: 6A 00                                         push 0
                                                        
0000020C: E8 08 00 00 00                                call ..continue?0000680
00000211: 43 61 70 74 69 6F 6E 00                       db 'Caption',0
                                                        ..continue?0000681:
                                                        
00000219: E8 10 00 00 00                                call ..continue?0000682
0000021E: 48 6F 77 20 61 72 65 20 79 61 3F 21           db 'How are ya?! ',13,10,0
          20 0D 0A 00                                   ..continue?0000682:
                                                        
0000022E: 6A 00                                         push 0
                                                        
00000230: FF 15 3C 20 40 00                             call [MessageBox]
   
    




How does this -

Code:

00000219: E8 10 00 00 00                                call ..continue?0000682
0000021E: 48 6F 77 20 61 72 65 20 79 61 3F 21           db 'How are ya?! ',13,10,0
          20 0D 0A 00                                   ..continue?0000682:

    


push db 'How are ya?! ',13,10,0 onto the stack so "call [MessageBox]" has the correct stack parameters. I understand with "call ..continue?0000682", EIP is pointing to 0000021E (start of the line 'How are ya?! ',13,10,0' ) but what occurs so that this gets pushed on the stack? Hope my mumbling is clear.

Also is this type of coding inefficient? Is it preferable to place strings in the data section?

Thanks

[edit update]

Well well well, this code seems to work just fine

Code:
        ;invoke MessageBox, 0, <"How are ya?! ",13,10>, "Caption", 0

        push 0

        call @f
        db 'Caption',0
        @@:

        call @f
        db 'How are ya?! ',13,10,0
        @@:

        push 0

        call [MessageBox]

    



But what's happening?
Post 08 Nov 2006, 22:53
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 Nov 2006, 23:52
yes, this is the trick, that you can do:
Code:
push ..data:
jmp ..next
..data db "string",0
..next:    

with this:
Code:
call ..next
db "string",0
..next:    


but the second method is INEFFICIENT!!!! Note that FASMLIB doesn't use it too (it has idata{}, udata{} macros). Processor has cache for pairing CALL/RET, and unpairing these costs something - imprediction for every return.

and yes, it is preferable to place strings in data section. or more, in read-only data section, so you catch bug with modifying these data
Post 08 Nov 2006, 23:52
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
MichaelH



Joined: 03 May 2005
Posts: 402
MichaelH 09 Nov 2006, 02:23
I guess I should have reread the Intel Opcodes and Mnemonics before asking such a stupid question.


Quote:

CALL - Procedure Call
Usage: CALL destination
Modifies flags: None
Pushes Instruction Pointer (and Code Segment for far calls) onto
stack and loads Instruction Pointer with the address of proc-name.
Code continues with execution at CS:IP.



So call ..continue?0000682 -

Pushes Instruction Pointer - so ESP now point to 0000021E:

Code continues with execution at CS:IP (EIP) - continues at 0000022E:


So the next "push 0" means esp will then point to 0000022E: and hence the string db 'How are ya?! ',13,10,0 is all set to be popped off .... I love assembler more by the day Smile


Thanks for the tricks Vid.
Post 09 Nov 2006, 02:23
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.