So I've written this very simple program which I had hoped was going to display a smiley face on screen.  I've worked through a few syntax issues due to using fasm instead of masm which what I think this app was originally written in.  Now the program compiles with no errors, but when I run it I get the "firstapp.EXE has encountered a problem and needs to close.  We are sorry for the inconvenience." error in XP.  The code follows.  Thanks in advance for your help!

format PE


Mov ah, 2
Mov dl, 1
Int 21h

mov ah, 4ch
mov al, 00h
int 21h
Posted on 2009-07-28 16:26:21 by herbally
DOS apps are typically assembled/compiled/linked to MZ or COM format.

Try: format MZ instead of format PE.
Posted on 2009-07-28 23:49:17 by SpooK
Thanks a bunch SpooK! I wasn't sure from reading the tutorial that I was reading whether it was supposed to be in DOS or what.  Not that it matters, I'm too green to have known that DOS requires the MZ format.  That did make it execute properly though, so thanks again.

Posted on 2009-07-29 09:53:11 by herbally
FYI: 16-bit applications (be it for DOS or 16-bit Windows) won't run under 64-bit OSes (without any third-party emulation that is).
Posted on 2009-07-29 10:15:14 by ti_mo_n
Thanks for that tidbit ti_mo_n.

another quick question...

syntax for fasm differs quite a bit it seems from masm/tasm.

I'm trying to expand this simple app to display a string rather than a single character.  I finally figured out how to specify the data segment, but I can't seem to figure out the syntax to put the segment address of my string into the AX register.

In MASM I think the code would be like this:

mov ax, SEG myString

I've been reading through the FASM pdf help file along with all the examples that come with FASM and I can't seem to find this info anywhere.  Someone mind throwing me a bone?

Posted on 2009-07-29 12:07:13 by herbally
You shouldn't have to screw around with setting the data segment, It should be set by the executable loader. I'm not versed in fasm, however, you should be able to address just the address.
mov ax, addr myString

then when refering to ax as a point in memory, it will automatically refer to "ds:"

myString db "abcdefghijklm","$","nopqrstuvwxyz","$"

mov si, addr myString ;changed from ax to the source index for a read
lodsb ;could be thought of as a mov al, ds:si
inc si ;go to the next character
cmp al, 24h ;are we at the end? (24h = "$")
jne @B ;if we aren't go do it again
;si is pointing to the next string aka "nopqrstuvwxyz"

This would be masm syntax, and not accomplish anything, but would show you a way of addressing myString. As you can see, we didn't mess with ds at all as lodsb assumes to read at ds:si.
Posted on 2009-07-29 13:57:04 by jakor
I'm not sure if FASM supports "mov ax, <segment>" when generating MZ executables (and I'm too lazy to check the documentation right now - you do that ;)), but if you're using one of the smaller memory models, "push cs" + "pop ds" should do the trick (and is 3 bytes shorter in size :P).
Posted on 2009-07-29 15:26:50 by f0dder
lodsb ;could be thought of as a mov al, ds:si
inc si ;go to the next character

The lodsb instruction also increments the si register.
The inc esi instruction would thus skip every other character and could also possibly skip the end-of-line character $.
Posted on 2009-07-29 21:07:30 by Raymond