flat assembler
Message board for the users of flat assembler.

Index > Main > FASMLIB tutorial part 2 - Hello World

Author
Thread Post new topic Reply to topic
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Last time we ended with FASMLIB win32 program template:

Code:
include "%FASMINC%/win32axp.inc"

SYSTEM equ win32
include "fasmlib/fasmlib.inc"
include "fasmlib/process.inc"
include "fasmlib/mem.inc"
include "fasmlib/str.inc"

.code

start:
        ;initialize modules
        call mem.init
        jc error
        call str.init
        jc error

        ; ... do the work ...

        ;uninitialize modules
        call str.uninit
        jc error
        call mem.uninit
        jc error
        
        ;exit process
        push dword 0
        call exit

error:
        ;try to uninitialize what we can, without further error checking
        call str.uninit
        call mem.uninit

        ;exit with code -1
        push dword -1
        call exit

.data
        IncludeIData
        IncludeUData

.end start    

Today we are gonna display some string on console. First we need to create a console. There is a flag in windows PE (win32 EXE) file header, that says Windows to create console for us. You can set this flag by using console keyword in format PE line. In previous example there was no format PE, so win32axp.inc used default format PE GUI. Now we will set up format ourselves, like this:

Code:
format PE console

;------------ rest of code stays same: ----------------
include "%FASMINC%/win32axp.inc"

SYSTEM equ win32
include "fasmlib/fasmlib.inc"
include "fasmlib/process.inc"
include "fasmlib/mem.inc"
include "fasmlib/str.inc"

.code

start:
        ;initialize modules
        call mem.init
        jc error
        call str.init
        jc error

        ; ... do the work ...

        ;uninitialize modules
        call str.uninit
        jc error
        call mem.uninit
        jc error
        
        ;exit process
        push dword 0
        call exit

error:
        ;try to uninitialize what we can, without further error checking
        call str.uninit
        call mem.uninit

        ;exit with code -1
        push dword -1
        call exit

.data
        IncludeIData
        IncludeUData

.end start    
Try to run this example, not from command line, you should see console window appear.



Now we have console created, how to access it? Right now, it can be done with stream module. I hope you know what is stream, i am not going to explain right now,i just can say it's something you read/write data from/to. For example file can be stream too, but when you take it as stream you only can read it once, and you cannot seek in it.

You access streams through stream handles (they are just 32bit dwords). These are either returned from some procedures, or you can use predefined system handles:

When we have console created, Windows creates 3 default streams for us:
STDIN - standard input - you can read input from here, eg. what user writes to console
STDOUT - standard output - you write all your output (except errors) to console through this stream
STDERR - standard error - you write error information and debugging information to this stream. Normaly this stream is same as STDOUT, but if user wants he can redirect it so he can separate normal and error/debug output.

After you initialize stream module, you can access these streams thorugh these variables containing predefined handles: stream.stdin, stream.stdout, stream.stderr.

First we will only write to stdout. To write to stream we can use procedure stream.writebuf with arguments: stream_handle, buffer_address, buffer_size, which writes to stream data from buffer of given size. So the code will be:

Code:
format PE console

include "%FASMINC%/win32axp.inc"

SYSTEM equ win32
include "fasmlib/fasmlib.inc"
include "fasmlib/process.inc"
include "fasmlib/mem.inc"
include "fasmlib/str.inc"
include "fasmlib/stream.inc"                            ;we are using  this module

.code

start:
        ;initialize modules
        call mem.init
        jc error
        call str.init
        jc error
        call stream.init                                ;initialize "stream" module
        jc error

        ;display _string
        ;remember arguments are pushed in reversed order (right to left)
        push dword _string_length                       ;size of data
        push dword _string                              ;pointer to buffer with data
        push [stream.stdout]
        call stream.writebuf
        jc error

        ;uninitialize modules
        call stream.uninit                              ;uninitialize "stream" module
        jc error
        call str.uninit
        jc error
        call mem.uninit
        jc error
        
        ;exit process
        push dword 0
        call exit

error:
        ;try to uninitialize what we can, without further error checking
        call stream.uninit                              ;don't forget it here
        call str.uninit
        call mem.uninit

        ;exit with code -1
        push dword -1
        call exit

.data
        _string db "Hell o' world"                      ;data we will write to console
        _string_length = $ - _string                    ;numeric constant holding data length
        IncludeIData
        IncludeUData

.end start    

so in data segment we defined data we wanted to write, and we used stream.writebuf to display it, i hope it's clear. This is working HelloWorld example.

We can also signal error, in a simple way (for now). In case of error, we can try to write "Error" to stderr. It isn't always possible, like when stream module isn't initialized yet, so we won't check error on that one:
Code:
format PE console

include "%FASMINC%/win32axp.inc"

SYSTEM equ win32
include "fasmlib/fasmlib.inc"
include "fasmlib/process.inc"
include "fasmlib/mem.inc"
include "fasmlib/str.inc"
include "fasmlib/stream.inc"

.code

start:
        ;initialize modules
        call mem.init
        jc error
        call str.init
        jc error
        call stream.init
        jc error

        ;display _string
        push dword _string_length
        push dword _string
        push [stream.stdout]
        call stream.writebuf
        jc error

        ;uninitialize modules
        call stream.uninit
        jc error
        call str.uninit
        jc error
        call mem.uninit
        jc error
        
        ;exit process
        push dword 0
        call exit

error:
        ;try to write error message to stderr
        push dword _error_length                        ;new things
        push dword _error                               ;
        push [stream.stderr]                            ;
        call stream.writebuf                            ;
        ;no error checking here. stream.writebuf is free to fail Smile

        ;try to uninitialize what we can, without further error checking
        call stream.uninit
        call str.uninit
        call mem.uninit

        ;exit with code -1
        push dword -1
        call exit

.data
        _error db "Error"                               ;new things here too
        _error_length = $ - _error                      ;
        _string db "Hell o' world"
        _string_length = $ - _string
        IncludeIData
        IncludeUData

.end start    


I think that's all for now, i don't want to mess too much things into this chapter. Next time we will learn how to use dynamic string library, get deeper on errors, and then later we will see how things are really used in FASMLIB, eg. i will explain some high-level macros to ease your work.

PS: if you didn't know what redirecting stream is, try compiling this example, like
fasm.exe test.asm test.exe
and then run it with
test.exe >output.txt
You will see all output goes to file output.txt, handy thing. This is what streams are for.
Post 29 Mar 2006, 01:21
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number 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 YouTube, Twitter.

Website powered by rwasa.