flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Macro to display string

Author
Thread Post new topic Reply to topic
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
How to create macro, which could print string like that:

Code:
prints "hi there!"    


I saw different sujestions but they are a bit complicated.
I tried to do that with this code

Code:
macro prints str
{
    local .bytes
        call .bytes
        db str, 24h
        mov ax, ax
    .bytes:

    mov dx, [.bytes]
    mov ah, 9h
    int 21h
}
    


but it doesnot work for long strings.
Help please...

P/s - the second question, that I can not use display directive in my code: for example when I type

Code:
display 'hi'
    


it compiles but does noting...
Post 18 Feb 2013, 18:10
View user's profile Send private message Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 518
Location: Munich
shutdownall
The message is displayed in the compile window if you press CTRL-F8 in the IDE (FASMW.EXE).


Description:
Filesize: 33.74 KB
Viewed: 3071 Time(s)

hi.gif


Post 18 Feb 2013, 18:29
View user's profile Send private message Send e-mail Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
So 'display' is useless in DOS? (because it is my target platform)
And what about function to display the string?
Post 18 Feb 2013, 18:40
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
deathmood,

Console compiler displays these messages along its output. FASMD can put them into its clipboard.

About prints macroinstruction: mov dx, [.bytes] in this context is equivalent to mov dx, 0x168B (because it actually loads dx with contents of memory at .bytes instead of that address itself), so I doubt it'll work even for short strings. Moreover, call pushes address of that string on stack and you never (explicitly) pop it off (or use in any other way).
Code:
macro prints [str*]
{
common
  local ..code
        call    ..code
        db      str, 24h
..code: pop     dx
        mov     ah, 9h
        int     21h
}    
Another way to do it:
Code:
macro prints [str*]
{
common
  local ..code, ..data
        jmp     ..code
..data: db      str, 24h
..code: mov     dx, ..data
        mov     ah, 9h
        int     21h
}    
Post 19 Feb 2013, 07:26
View user's profile Send private message Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
baldr,

I get some raw characters while using both your methods, e. g. for

Code:
prints "hi there)))) !!!!!"
    


I get this:


Description: where I am wrong((( ??
Filesize: 25.03 KB
Viewed: 3047 Time(s)

err.png


Post 19 Feb 2013, 07:54
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
See here: http://board.flatassembler.net/topic.php?t=7961
See below, as i do not think he as a print string


Last edited by Dex4u on 19 Feb 2013, 08:25; edited 1 time in total
Post 19 Feb 2013, 08:13
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Something like this:
Code:
macro PRINT String{
        local .Done
        local .a 

                mov dx, .a
                mov     ah, 9h
                int     21h
                jmp .Done 
 
        .a db String,24h
 
        .Done: 
}
    
Post 19 Feb 2013, 08:23
View user's profile Send private message Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
Dex4u,

I do not understand why, but it also prints many 'raw' characters as it was in my previous post...((( even more...
Post 19 Feb 2013, 08:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17714
Location: In your JS exploiting you and your system
revolution
deathmood: Post your code.
Post 19 Feb 2013, 09:28
View user's profile Send private message Visit poster's website Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
Code:

format MZ

use16
stack 0x100
entry _CODE@16:_start

;
macro prints str
{
    local .bytes
        call .bytes
        db str, 0x24

    .bytes:
        pop dx
        mov ah, 9
        int 0x21
}

segment _DATA@16 use16
    msg db 'hi!', 0xd, 0xa, 0x24

segment _CODE@16 use16
    _start:
        mov ax, _DATA@16
        mov ds, ax

        prints 'hi there))) !!!!'

        mov ax, 0x4c00
        int 0x21
    ret

    


I have found the strange thing: if I do not define any variables in my _DATA@16 segment macro 'prints' works fine. But after defining some variables raw symbols begin to appear(((

Why??((
Post 19 Feb 2013, 09:41
View user's profile Send private message Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
Hey! Maybe I've chosen wrong way to achieve that?
Maybe there are some other ways? Any sujestions?
Post 19 Feb 2013, 10:54
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
deathmood,

Yep, you're getting offset in _CODE@16 segment as a value of dx, while int21/09 expects offset in ds segment (_DATA@16), which is one paragraph below.

There are many ways to handle this, probably easiest one of them is to use tiny memory model, when cs == ds (pure tiny memory model assumes cs == ss too, but MZ executable places stack elsewhere by default). Put code and data in single segment (or forget about segments altogether for a while and use .COM executable output format).
Post 19 Feb 2013, 15:58
View user's profile Send private message Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
baldr,

Maybe there is another way to do that (using different macro features or else) ? because I do not want to use .com file neither having one segment...
Post 19 Feb 2013, 16:42
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
COM file code has ~560Kb of data at its disposal.
Post 19 Feb 2013, 18:10
View user's profile Send private message Send e-mail Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
So there is NO way to solve that ???
Post 19 Feb 2013, 18:16
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
Why? There is always a way - I just forgot how to do it!
Try to create an MZ file and print a string without using any macros.
Make it work and then move on to doing it with macro.
At least you will have a working starting point.
Post 19 Feb 2013, 23:09
View user's profile Send private message Send e-mail Reply with quote
deathmood



Joined: 17 Feb 2013
Posts: 16
deathmood
So for .com files my macro can look like this:

Code:

use16
org 0x100

macro prints [str*]
{
    pusha

    if str in <0xd, 0xa, 9>\
        | str eqtype ''

        call @f
        db str, 0x24
        
        @@:
            pop dx
    else
        mov dx, str
    end if

    mov ah, 9
    int 0x21

    popa
}

_start:
    prints 0xd, 0xa, 9
    prints 'hi!', 0xd, 0xa
    mov ax, msg
    prints ax, 0xd, 0xa
    prints msg

    int 0x20
ret

msg db 'hey there!', 0x24

    


it can accept strings directly, addresses of strings in registers and variables
it can also handle 3 special characters - 0xd (CR), 0xa (LF) and 9 (TAB)

it is good because of its simplicity comparing to other samples here (on forums).
Post 20 Feb 2013, 08:46
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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.