views:

223

answers:

4

Hello.

I've literally only just started looking to learn Assembly language. I'm using the NASM assembler on Windows Vista.

Usually, when I begin to learn a new language, I'll copy someone else's Hello World code and try to understand it line-by-line. However, I'm finding it suprisingy difficult to find a Hello World program that doesn't reference other libraries! You see, there's no point trying to understand each line of the code if it is closely linked with a whole library of additional code!

One of the reasons I want to learn Assembly is so that I can have near complete control over the programs I write. I don't want to be depending on any libraries.

And so my question is this: Can anyone give me NASM-compatible Assembly code to a completely stand-alone Hello World program that can output to the Windows Vista console?

Alternatively, I appreciate that a library may be required to tell the pogram WHERE to print the output (ie. the Windows console). Other than that, I can't see why any libraries should be required. Am I overlooking anything?

+3  A: 

Here is how:

       .text
LC0:
        .ascii "Hello, world!\12"
.globl _main
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $4, %esp
        pushl   $-11
        call    _GetStdHandle@4
        pushl   $0
        leal    -4(%ebp), %ebx
        pushl   %ebx
        pushl   $14
        pushl   $LC0
        pushl   %eax
        call    _WriteFile@20
        movl    $0, %eax
        leave
        ret

You won't get around using operating system functions though. The downside of not using a library (such as the C library) is that you are coupling yourself to the specific OS.

Johannes Rudolph
Newbie
The calls to `_GetStdHandle@4` and `_WriteFile@20` are OS-specific. As are all the lines before, between and after them. Basically the whole file minus the `.ascii` directive is OS-specific. The `main` function is an OS requirement. The stack frame setup and teardown is an OS requirement. Pushing the parameters on the stack before each function call is an OS requirement. So basically all but one line is an OS requirement.
JUST MY correct OPINION
Conversion is not as hard as it might seem. Simply drop the "l" on most of the instructions and switch the order of the operands. Remove $ and %. So 'subl $4, %esp' becomes 'sub esp, 4'. LEA is a little weird, that one becomes "lea ebx, [ebp+4]".
SoapBox
Thanks SoapBox. I now only get 3 errors, starting with line 1: "Attempt to define a local label before any non-local labels". I haven't changed this line from Johannes original response. Should I?
Newbie
Aha! I've just installed MinGW and got Johannes code working having followed the Wikibooks tutorial that he linked too. I've also made progress using NASM, using different code from "http://home.comcast.net/~fbkotler/clueless.html" and it doesn't call any outside subroutines! (Does this mean it doesn't use any libraries?)
Newbie
A: 

Windows loads kernel32.dll and ntdll.dll libraries for all programs (independently from whether you use them on not). And you have to use them because low-level interface to the operating system depends on your processor and its version (i.e. it may change after some windows updates).

Ha
Surely I'd only actually use these if a line in my code references a routine within them? So, does the code in the above answer refer to them at any point?
Newbie
Yes, it does. And no, you will use them regardless of your code - Windows loads kernel32.dll and ntdll.dll libraries for *all* programs.
Ha
+1  A: 

As an alternative you could write a boot loader that prints "Hello, World" to the console directly through video memory. Then you have virtually nothing between you and the bare metal. You can find the instructions for making a boot loader pointed to by the OSDev Wiki. Start by reading that page to get an explanation of the concepts and ideas. After that follow the external link to the Hello World Bootloader. Note that the tutorial there uses the BIOS (a library) to print the message. You can, however, search around on the OSDev Wiki for information on how to print messages to the screen without the BIOS and make your required alterations.


Edited to add:

I strongly recommend that you use some kind of virtualisation for this activity. Don't be messing with boot sectors on your hard drive unless you REALLY know what you're doing.

JUST MY correct OPINION
An interresting suggestion - thank you, I'll give it a try. My main priority is still to get this working on Windows, so I'd welcome any more answers.
Newbie
If you do it under Windows, you will be using libraries. You will be using layers of libraries slathered atop layers of libraries, indeed. Not only do you have `kernel32.dll` and `ntdll.dll` in the loop, you have whatever libraries they load (too lazy to check which at the moment) as well as the HAL and any device drivers involved (which in this case would at the very least involve your video device drivers).
JUST MY correct OPINION
Oh, no worries about the boot sector stuff. I'm well aware of the dangers and have a old spare machine for this kind of experimenting :)
Newbie
A: 

Windows is designed such that everything is in a library. The most basic library is Kernel32.dll, which includes functions for writing and reading files and other very basic operations. (Writing to the console is really just writing to a special file.)

On Linux, basic system functions are not in libraries, they are instead in "system calls" which are accessed through interrupt 80. Thus, on Linux it is possible (and pretty easy) to write some fairly advanced programs without any "library" calls at all.

But, you should probably embrace a few libraries. The whole point of libraries is to make your life easier. Go ahead and use the C standard library so that you can have some basic console and file input/output. From there you might not find any place where you really need libraries that you can't make yourself.

SoapBox
System calls are just an implementation detail for a library. Whether it's done through an interrupt gate or a stub function that goes through another variety of protection gate is irrelevant: you're still using libraries.
JUST MY correct OPINION
OK, if a library file is needed to write to the console I'll happily embrace it. All I want, for the moment, is to output hello world. Referring to Ha's answer (and comments) it appears as though this Kernel32.dll library is already being used in Johannes code, so I'll continue to try and get it converted and working.
Newbie