Printing a character with NASM

Programming, for all ages and all languages.
Post Reply
gsingh2011
Member
Member
Posts: 83
Joined: Tue Feb 03, 2009 11:37 am

Printing a character with NASM

Post by gsingh2011 »

I'm using NASM with Cygwin. I thought that you could print characters using int 21h with NASM, but apparently that's only a DOS command? How do I do it in win32?
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: Printing a character with NASM

Post by Love4Boobies »

Open the file called CON and write to it. Here's a C example to illustrate the point:

Code: Select all

#include <stdio.h>

int main(void)
{
    FILE *f = fopen("CON", "w");
    fputs("hello, world!", f);
    fclose(f);
}
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Printing a character with NASM

Post by Combuster »

If you have to do it the portable way, just write to stdout and have the C runtime take care of the rest. But the OP did not ask for C code.

If you want native windows, use the console functions, which also gives you control over colours and whatnot. You only need three functions to get started, in order:
AllocConsole (if you didn't link for a console application and none is therefore created by default)
GetStdHandle
WriteConsole
which you can just import and call from assembly.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
gsingh2011
Member
Member
Posts: 83
Joined: Tue Feb 03, 2009 11:37 am

Re: Printing a character with NASM

Post by gsingh2011 »

Ok, I followed the example here and got it working: http://codewiki.wikispaces.com/winstdout.nasm

I shortened it to the following code:

Code: Select all

[list -]
%include 'win32n.inc'
[list +]

section .bss use32
section .data use32
section .code use32
cpu 386

extern  WriteFile
extern  GetStdHandle
extern ExitProcess
import WriteFile kernel32.dll
import GetStdHandle kernel32.dll
import ExitProcess kernel32.dll

section .code
..start:

	mov eax,1
	push eax
	mov eax,1
	pop ebx
	add eax, ebx

	push     STD_OUTPUT_HANDLE
	call    [GetStdHandle]          ;Get stdout
	mov     [stdout_handle], eax    ;Save the handle

	;Write a message to stdout
	push    dword 0                 ;error code
	push    dword 0                 ;octets_written
	push    dword textlen           ;in octets to write
	push    dword text1             ;in buffer
	push    dword [stdout_handle]   ;in handle
	call    [WriteFile]             ;Write message

exit:

        push    dword 0                    ;Point at error code
        call    [ExitProcess]
        jmp     exit                    ;Should never reach here

section .data
stdout_handle:  dd      0
text1:             db      53, 13, 10
textlen:        equ        $ - text1
and it works fine and outputs the number 5. But I did some calculations above, (1+1) and I want to output the result (don't worry about the roundabout way the numbers are added). I tried storing the result (eax) in another register (ebx) and then replacing push dword text1 with push dword ebx, but that didn't work.

EDIT: Nvmd, I got it. mov [text1], eax does the trick.
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: Printing a character with NASM

Post by Love4Boobies »

Combuster wrote:If you have to do it the portable way, just write to stdout and have the C runtime take care of the rest.
That only works if you can guarantee that the C runtime actually prints to the console and not somewhere else.
Combuster wrote:But the OP did not ask for C code.
Indeed, so think of it as pseudocode. The point was writing to the CON file (and maybe use ANSI codes for colors, etc.). According to MSDN, both techniques should work and this one is apparently what the OP decided to go for. However, I'm not sure it's as flexible because NT added all sorts of functions to deal with security and so forth, but at least it works on 9x. :)
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: Printing a character with NASM

Post by Gigasoft »

You do not need to call GetStdHandle. STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE can be used directly with the following functions.

ReadFile
WriteFile
CloseHandle
_lread
_lwrite
_lclose

Don't know of any others.

For text output, the functions from msvcrt.dll are often sufficient and easier to use. Don't reinvent something which is already there. The __getmainargs function, for example, is often overlooked and programmers invent their own way to read the command line.
Post Reply