News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

cant compile "hello world"

Started by WYVERN666, April 10, 2011, 05:17:53 AM

Previous topic - Next topic

WYVERN666

Hello all, im new learning asm, i tryed the SIMPLE "hello world":


.386
.MODEL flat, stdcall

.data
message   db "Hello world!",0

.code
main:
       mov   ax,seg message
       mov   ds,ax

       mov   ah,09
       lea   dx,message
       int   21h

       mov   ax,4c00h
       int   21h
end main


Assemble parameters: /c /coff /Cp /nologo
Link parameters: /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0

This gives me in line 9:
Quote
error A2004: symbol type conflict

I am using the WinAsm Studio, but i have the same error in the MASM32 Editor.

I tryed "mov ax,@data" in that line, but @data doesnt exists in MASM??.
ax must be eax?
In fact y tryed a lot of variants... but cant compile with anyone.

Someone can help me please?, thanks

MichaelW

Hi WYVERN666,

What I see is 16-bit DOS code with the position of the processor directive and the memory model (flat) set up for 32-bit code. This will not work. Are you trying to create a 16-bit DOS app or a 32-bit Windows app?
eschew obfuscation

Vortex

Hi WYVERN666,

If you wish to create a 16-bit DOS application, don't forget to get the 16-bit linker :

http://website.masm32.com/microsoft/Lnk563.exe

dedndave

this is a 32-bit console app
to assemble.....
ML /c /coff StdOut.asm
LINK /SUBSYSTEM:CONSOLE /OPT:NOREF StdOut.obj


        INCLUDE \masm32\include\masm32rt.inc

;----------------------------------------------------------

        .DATA

TestStr db 'Hello World!',13,10

        .DATA?

hStdOut      dd ?
BytesWritten dd ?

;----------------------------------------------------------

        .CODE

_main   PROC

        INVOKE  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hStdOut,eax

        INVOKE  WriteFile,hStdOut,offset TestStr,sizeof TestStr,offset BytesWritten,NULL

        INVOKE  ExitProcess,0

_main   ENDP

;----------------------------------------------------------

        END     _main

dedndave

this is a 32-bit windows app
to assemble.....
ML /c /coff MsgBox.asm
LINK /SUBSYSTEM:WINDOWS /OPT:NOREF MsgBox.obj


        INCLUDE \masm32\include\masm32rt.inc

;----------------------------------------------------------

        .DATA

TestStr db 'Hello World!',0

;----------------------------------------------------------

        .CODE

_main   PROC

        INVOKE  MessageBox,NULL,offset TestStr,offset TestStr,MB_ICONINFORMATION

        INVOKE  ExitProcess,0

_main   ENDP

;----------------------------------------------------------

        END     _main

dedndave

this is a 16-bit console app
to assemble.....
ML /c Hello16.asm
LINK16 Hello16.obj

(the linker may be named Link16 or Link563)

        .MODEL  SMALL

;----------------------------------------------------------

        .DATA

TestStr db 'Hello World!',13,10,24h

;----------------------------------------------------------

        .CODE
        ASSUME  DS:DGROUP

_main   PROC    FAR

        mov     ax,@DATA
        mov     ds,ax

        mov     dx,offset TestStr
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;----------------------------------------------------------

        END     _main

WYVERN666

Im using the flat model because im interested in 32-bit apps. (at least i understand the first lines of masm code xDD)

I learned that if i want to do 32-bit win apps i should go for the win api functions (like the examples from dedndave shows). Before this code y tryed mi "Hello World" using MessageBox, and others and have no problems with that... (or for now at least).

But i wanted to do a "hello world" in the console, and maybe thats why i am mixing diferent things. So, can i make console applications from win32 asm for windows? I really need using "invoke" to this things?.

When Vortext said mi code it is 16-bit code is because DX must be EDX and EX must be EAX?

Thanks for the help guys!, and the examples dedndave. by the way i thought that "ax,@DATA" was not for masm.

donkey

Hi,

The console uses the 32 bit console API, you should look at the following functions:

GetStdHandle
ReadFile
WriteFile

They will get you started. A very simple hello world for the console would be:

.686p
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include Windows.inc
include Kernel32.inc
includelib Kernel32.lib

.data
hConsole DD 0
szHello DB "Hello World",0
cbWritten DD 0

.code
Start:

invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hConsole,eax

invoke WriteFile,hConsole,offset szHello,11,offset cbWritten,NULL

invoke Sleep,5000

invoke CloseHandle, hConsole

invoke ExitProcess,0

End Start


Assemble as follows:

ml /c /coff /Cp "Console.asm"
link /SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 /OUT:"Console.exe" "Console.obj"
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

RuiLoureiro

Hi WYVERN666,

«im interested in 32-bit apps»
«But i wanted to do a "hello world" in the console»

Another example
Use Console Assemble & Link


.386
.model flat, stdcall
option casemap:none

; ********************* Console Assemble & Link *********************

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\masm32.inc
include     \masm32\include\user32.inc

includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\masm32.lib
;---------------------------------------------------
StandardOut     proto   :DWORD
StandardIn      proto   :DWORD, :DWORD
GetStrLen       proto   :DWORD
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

.data
message     db "Hello world!",0

inputbuffer db 20 dup (0)

.code
start:

    invoke  StandardOut, addr message           ; Print message

    ;
    ; Stop and wait for input then exit
    ; ---------------------------------
    invoke  StandardIn, addr inputbuffer, 0     ; some Input
    invoke  ExitProcess, 0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Input:    pText points to a null terminated string
;
StandardOut     proc        pText:DWORD
                LOCAL       StdHandle, Written:DWORD

                invoke      GetStdHandle, -11       
                mov         StdHandle, eax

                invoke      GetStrLen, pText

                invoke      WriteFile, StdHandle, pText, ecx, ADDR Written, 0

                ;invoke      CloseHandle, StdHandle

                mov         eax, Written
                ret
StandardOut     endp
;-------------------------------------------------------
StandardIn      proc        pBuffer:DWORD, Len:DWORD
                LOCAL       StdHandle, Read:DWORD

                invoke      GetStdHandle, -10   
                mov         StdHandle, eax

                invoke      SetConsoleMode, StdHandle, 7   
                invoke      ReadFile, StdHandle, pBuffer, Len, ADDR Read, 0

                ;invoke      CloseHandle, StdHandle
                mov         eax, Read
                ret
StandardIn      endp
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
GetStrLen       proc    pStr:DWORD

                mov     edx, [esp + 4]          ;pStr
                xor     ecx, ecx
                jz      short @F
           
    next:       add     ecx, 1           
    @@:         movzx   eax, byte ptr [edx + ecx]
                cmp     al, 0
                jne     short next

                ret     4
GetStrLen       endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef               
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
END start


dedndave

my first example is a 32-bit console app   :bg
i did not close the standard handle, because you do not need to
and - i used the SIZEOF operator to get the string length - WriteFile requires the length
normally, we use null-terminated strings, instead, as RuiLoureiro demonstrated

in the masm32 package, there is a macro named "print" that does all the leg-work for you
it uses the masm32 library "StrLen"  function to get the length
so, all you have to do is pass it the address of a null-terminated string
pre-written macros and functions are great, but you do not get to see the underlying code
the macro is in masm32\macros\macros.asm
it calls StdOut, which is in masm32\m32lib\stdout.asm
and that calls StrLen, which is in masm32\m32lib\strlen.asm
it is a good way to learn - see what is behind the functions you use
once you understand what is happening...
        print   chr$('Hello World!'),13,10
the chr$ macro creates the string and passes the address
the print macro has the capability to display additional characters after the string

as for @DATA, it is used in masm, for 16-bit applications
it must be upper-case   :P
it is actually an alias for DGROUP

it is important to notice how the strings are terminated differently in each type of app

RuiLoureiro

Quote from: dedndave on April 10, 2011, 03:41:34 PM
my first example is a 32-bit console app   :bg
i did not close the standard handle, because you do not need to

dedndave,
                you are right, we must remove CloseHandle, if not the second print doesnt appear

dedndave

i think that one is taken care of for you when you terminate   :P

WYVERN666

Ok, i see i am going to use invoke all the time xD. Good examples, thanks. I have a simple shorter version:

.386
.MODEL flat, stdcall

option casemap :none   ; case sensitive

; #####
   include \masm32\include\windows.inc
   include \masm32\include\kernel32.inc
   include \masm32\include\masm32.inc

   includelib \masm32\lib\kernel32.lib
   includelib \masm32\lib\masm32.lib
; #####

.DATA
HelloMsg  db 'Hello World',0

.CODE
START:
   invoke StdOut, addr HelloMsg
   invoke ExitProcess, 0
END START

but why is shorter than your examples?

dedndave

as i mentioned, i wrote them that way so you could see the underlying code
if you look at the StdOut function (masm32\m32lib\stdout.asm), you will see all the code

this one is even shorter than yours   :bg
        print   chr$('Hello World!'),13,10

dedndave

try this...
        INCLUDE \masm32\include\masm32rt.inc

;----------------------------------------------------------

        .CODE

_main   PROC

        print   chr$('Hello World!'),13,10
        inkey
        exit

_main   ENDP

;----------------------------------------------------------

        END     _main


masm32\include\masm32rt.inc takes care of all the preamble stuff
have a look in that file to see what it does   :U