11

Possible Duplicate:
how to write hello world in assembler under windows?

I've often heard of applications written using the language of the gods, assembly language. I've never tried though, and I don't even have a clue how to do it.

If I wanted to dabble, how would I go about doing it? I know absolutely nothing about what is required, although presumably some kind of compiler and Notepad.

Just purely out of curiousity, what would I need to write a "Hello World!" application?

Edit to add, I am running Windows 7 64bit

Edit to add, I wonder if there is an assembly language plugin for Visual Studio?

Community
  • 1
  • 1
NibblyPig
  • 51,118
  • 72
  • 200
  • 356

4 Answers4

7

For this, you gain nothing by writing 64-bit code -- you might as well stick to 32-bit code.

If you want output to a MessageBox, it could look like this:

.386
.MODEL flat, stdcall

MessageBoxA PROTO near32 stdcall, window:dword, text:near32,
        windowtitle:near32, style:dword

.stack 8192

.data
message db "Hello World!", 0
windowtitle   db "Win32 Hello World.", 0

.code
main proc
        invoke MessageBoxA, 0, near32 ptr message, near32 ptr windowtitle, 0
        ret
main endp
        end main

If you want output to the console, it's (strangely enough) a bit more complex:

.386
.MODEL flat, stdcall

getstdout = -11

WriteFile PROTO NEAR32 stdcall,     \
        handle:dword,                   \
    buffer:ptr byte,        \
        bytes:dword,                    \
        written: ptr dword,             \
        overlapped: ptr byte

GetStdHandle PROTO NEAR32, device:dword

ExitProcess PROTO NEAR32, exitcode:dword

.stack 8192

.data
message db "Hello World!"
msg_size equ $ - offset message

.data?
written  dd ?

.code
main proc   
    invoke GetStdHandle, getstdout
    invoke WriteFile,                   \
           eax,                         \
           offset message,              \
           msg_size,                    \
           offset written,              \
           0

    invoke ExitProcess, 0
main endp
        end main

In theory, moving to 64 bit code doesn't make a lot of difference -- for example, you can use the same functions in both. In reality, it's a bit painful, because the calling convention for 64-bit code is somewhat complex, and you can't use MASM's invoke for 64-bit code. Working code wouldn't be a whole lot more complex, but getting the code working probably would be a bit more work. The general idea is that for 64-bit code, you allocate space on the stack for all your parameters, but the first N parameters that are small enough to fit, go in registers.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • why is the writing to console so complicated? Back when I was doing assembly, writing a string was a trivial interrupt call... I think it was int 10h, but I can't recall for certain. It was like 4 instructions, no external libraries required. – rmeador Apr 16 '10 at 15:24
  • @rmeador:the length is mostly from the fact that they treat the console as a normal file, and WriteFile takes extra parameters we don't really care much about in this case. In theory you could use `WriteConsoleOutput` or something on that order, but it's non-trivial as well. – Jerry Coffin Apr 16 '10 at 16:06
  • Is this really all that's needed? I thought you'd have to set up loads of code sections and stuff. How can an ASM _Windows_ app be so much shorter than all the C++ code needed? It's only a little longer than a C++ console "Hello Word"! – Mr. Boy Apr 17 '10 at 08:33
  • @John:the C++ equivalent of the first one would be: `int main() { return MessasgeBox(NULL, "Hello World!", "Win32 Hello World", MB_OK); }`. – Jerry Coffin Apr 17 '10 at 13:29
  • Oh, OK. I never new you could access Win32 API so simply without a load of init code first. – Mr. Boy Apr 17 '10 at 14:12
2

Have a look at WinAsm.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
1

I advise you find a tool supporting Intel style ASM, rather than AT&T's horrible syntax.

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
1

In fasm:

include 'win32axp.inc'

.code
  start:
        invoke  AllocConsole
        invoke  WriteConsole,<invoke GetStdHandle,STD_OUTPUT_HANDLE>,tex,tex.size,dummy,0
        invoke  Sleep,-1
.end start

.data
tex     TCHAR   'Hello World!'
 .size  =       ($-tex)
dummy   rd      1   
Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47