NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: bunkdeath on July 14, 2010, 03:54:27 PM
-
hello there.. i tried a little code for hello world like
mov si, msg;
print:
lodsb;
cmp al, 0;
je halt;
mov ah, 0x0E;
int 0x10;
jmp print;
halt:
hlt;
msg db "Hello world!", 0
it didnot create any error but also didnot print hello world!
what is wrong in this code???
-
-----> Int 10/AH=0Eh @ RBIL (http://www.ctyme.com/intr/rb-0106.htm) <-----
-
I'll bet a nickle Ralf won't help him.
Where's your code loaded? (origin) Where's ds?
Best,
Frank
-
i am doing in windows platform, my origin was 0x100;
can you please show me code... i am beginer to assembly language. might be code help me to understand.
-
You've got all the code you need right there - just put "org 0x100" in front of it.
You should have learned from the link Keith gave you that bh wants to be the requested "video page" to write to. You want zero. If you're in a graphics mode, which you don't seem to be, you want the color/attribute in bl. My experience has been that this is not usually why this interrupt doesn't work - it's almost always that ds:si doesn't really point to your message - but throw in "mov bx, 7" to be safe.
"hlt" is a "privileged" instruction. It will probably be ignored - or else will crash your dos box. In any event, it will only halt the CPU until an interrupt (or reset) occurs. You probably want to end with "ret".
In Nasm syntax, ';' begins a comment. You don't need one at the end of every line. When I try to go back to C, I often forget the ';' (I didn't have a comment!), which causes a huge cascade of errors. So maybe putting ';' at the end of every line is a good idea - "just to stay in the habit". :)
Where'd you find the code you've got, Bunkdeath? What are you using for a textbook? I usually consider this too lame to post, but you might want to look at my "Clueless Newbie's Guide to Hello World in Nasm":
http://home.myfairpoint.net/fbkotler/clueless.html
It shows a slightly different way to say "Hello World"... but still in dos. I hate to be the one to break the news, if you haven't heard, but dos is dead. Still an okay way to learn a little assembly (if your OS supports it), but you won't want to spend much time with it. Consider downloading the NASMX package:
http://www.asmcommunity.net/projects/nasmx
It includes several examples of "real Windows programs".
Best,
Frank
-
Thanks Frank,
I tried ORG 0x100 too..But it did not work.
Yeah! those ';' are not necessary, but its my habit, since i am a C/C++ user. :D
I got my string program to work.
Actually i want to write assembly in BIOS interrupt.
And i am not using any books, I am onto net search.
But i am on my way, forums like yours helps us to improve.
Nice work admins.
I did new code
org 0x100;
lea si, [msg];
call print;
call akc;
lea si, [msg1]
call print;
call akc;
lea si, [msg2]
call print;
call akc;
jmp exit;
print:
mov ah, 0x0E;
print_do:
mov al, [si];
cmp al, 0;
je ok;
int 0x10;
inc si;
jmp print_do;
ret;
ok:
ret;
akc:
mov ah, 0x00;
akc_do:
int 0x16;
cmp al, 0x0D;
je ok;
jmp akc_do;
exit:
ret;
msg db 'Press return key to continue...',0x0D,0x0A,0
msg1 db 'Again...' ,0x0D,0x0A,0
msg2 db 'More...', 0x0D,0x0A,0
Sorry for another question,
But when created those printing part(label ones), and included, error occurred saying "system does not support full screen mode" !!! what is that?
My OS is W7 x86
Can you say what should be done to include a file. Because writing those code all the time is real boring.
-
%include "myfile.inc"
That's easy.
After that, I'm confused. Is your program working or not? Did you try the "mov bx, 7"? That error message "sounds like an OS problem to me!" :)
Best,
Frank
-
Before I posted you my previous post, my code made made error saying "system does not support full screen mode".
But when I, today, again did the same code, it made some character print out...
My code is like this
org 0x100;
%include "print.asm";
lea si, [msg];
call print;
mov ah, 0x00;
int 0x16;
call AA;
mov ah, 0x0E;
lea si, [return];
call print;
mov al, al;
mov bh, 0;
int 0x10;
lea si, [return];
call print;
lea si, [msg_akc];
call print;
call akc;
ret;
msg db 'Enter any character',0x0D,0x0A,0
msg_akc db 'Press return key to continue' ,0x0D,0x0A,0
return db 0x0A,0x0A,0
A db 'You pressed A',0;
AA:
cmp al, 65;
je ae;
ret;
ae:
lea si, [A];
call print;
ret;
print.asm
print:
mov ah, 0x0E;
print_do:
mov al, [si];
cmp al, 0;
je ok;
int 0x10;
inc si;
jmp print_do;
ret;
ok:
ret;
akc:
mov ah, 0x00;
akc_do:
int 0x16;
cmp al, 0x0D;
je ok;
jmp akc_do;
exit:
ret;
Is that some kind of location error??
This was my output
??รจ?<
My desired output was
Enter any character
You pressed A ==> if i pressed key A
Press return key to continue
This was my output when I did all code in a single file.
But again i want to tail a question :D :)
I wanted to print the character, user pressed.
What modification should I make to print character in that code??
Thanks,
-
Well, you put your subroutines first thing in your file, so the first thing that happens is it prints whatever garbage si is pointing to, and exits. "%include" essentially just does a cut-and-paste, so put it where you want the text to appear.
org 0x100;
; section .text
; start
; print the prompt
lea si, [msg];
call print;
; get a key
mov ah, 0x00;
int 0x16;
; print it ?
mov bx, 7;
mov ah, 0xE;
int 0x10;
; see if it was 'a'
call AA;
; mov ah, 0x0E; ???
; print newline
lea si, [return];
call print;
; mov al, al; ??? will be zero when "print" returns, no?
;mov bh, 0;
;int 0x10;
; print another newline
lea si, [return];
call print;
; print second prompt
lea si, [msg_akc];
call print;
call akc;
; exit
ret;
AA:
cmp al, 65;
je ae;
ret;
ae:
lea si, [A];
call print;
ret;
%include "print.asm";
; section .data
msg db 'Enter any character',0x0D,0x0A,0
msg_akc db 'Press return key to continue' ,0x0D,0x0A,0
return db 0x0A,0x0A,0
A db 'You pressed A',0;
And here's "print.asm"...
print:
mov ah, 0x0E;
mov bx, 7;
print_do:
mov al, [si];
cmp al, 0;
je ok;
int 0x10;
inc si;
jmp print_do;
; ret; never reached!
ok:
ret;
akc:
; get a character
mov ah, 0x00;
akc_do:
int 0x16;
; print character entered?
mov ah, 0xE;
mov bx, 7;
int 0x10
; until "enter" pressed
cmp al, 0x0D;
je ok;
jmp akc_do;
;exit: never reached!
; ret;
I'm not sure that'll do what you want, but it should do something before exiting, at least. :)
Consider writing just the comments first, then fill in code to do what you said you wanted to do. I find it helps - when I don't do it, I often wish I had! :)
Best,
Frank
-
Actually i was in the process of learning getting characters, printing characters, getting string and printing string.
Now I can print character and string and input for a character.
My problem here is, I cannot print the character that is input.
When I check the input character present in AL register, it works fine, but when I try to print that character it does not print.
Is that due to the different page?
This is not working...
org 0x100
mov ah, 0x00
int 0x16
mov ah, 0x0E
int 0x10
What I know is, the input character is present in AL register, and when we call interrupt 0x10 with ah 0x0E, it should print out the character in AL register. Am i right?
Thanx
-
Looks to me like that should work, but if it doesn't, it doesn't. My opinion doesn't count. Could be a "video page" issue - probably - or could be that bl is controlling color. Although RBIL says "in graphics modes", I seem to recall hearing (not encountering it) that some (laptop?) video bioses do it. Black on black is just as good as not printing at all. If you feel like experimenting, try 'em one at a time. If this works, I owe Keith a nickel! :)
As I recall, dos used to start a .com program with bx=0, so the "page" should be okay anyway - until you alter bx and it mysteriously quits working. I got in the habit of doing "mov bx, 7", just to be sure. As I recall, neither bh nor bl made any difference - but that was on different hardware... and we've got "drivers" to contend with.
Which reminds me... I looked up that error message you mentioned:
http://www.mydigitallife.info/2007/06/27/workaround-to-this-system-does-not-support-full-screen-mode-in-windows-vista/
If it "just started working", great! If it should crop up again, you might want to look at that (none of the workarounds are considered "good"). Reserving a small partition for "real dos" (freedos, or so) is good too - if you intend to experiment with getting into protected mode, you'll want that. I have such a partition, but "hate to reboot", so I can't conveniently try dos/bios stuff. If you/we get completely stumped, I will...
When you get to "input a string", don't let 'em overrun the buffer! If you do this accidentally, it's a "bug". If you do it on purpose, it's an "exploit". And we've got enough "exploits", thanks. :)
Let us know if you find the "trick" to that input-and-print problem!
Best,
Frank
-
Ah!!!! I found what was the mistake. Actually its not mistake, its due to confusion. when i did input using dos interrupt, there was some value to AH(forgot now, might be the same 0x00) which was input with echo. But in case of bios, that value is just to input, not to echo. Actually i got the string, but what i thought was the input character is echoed. But it was printed by my code... :D
Thanks
-
[org 0x100]
jmp start
message db'hello world',0dh,0ah,0
print:
mov dl,[si]
cmp dl,0
jz over
mov ah,02h
int 21h
inc si
jmp print
over:
ret
start:
mov ax,cs
mov ds,ax
xor cx,cx
mov si,message
call print
jmp $
-
Kewl!
Where's the bios interrupt?
Why:
mov ax, cs
mov ds, ax
? Dos should load with cs=ds=es (for a .com file only!). Doesn't hurt to make sure. Good habit, to make sure ds actually points to your data!
Why:
xor cx, cx
? Won't hurt.
Why:
jmp $
? We usually try to NOT hang the machine...
Here's a different bios interrupt:
org 100h
segment .data
; message in char,attrib,char,attrib... format
msg1 db 'M',01h,'a',02h,'n',03h,'y',04h,' ',05h,'T',06h
db 'h',07h,'a',08h,'n',09h,'k',0Ah,'s',0Bh,' ',0Ch
db 't',0Dh,'o',0Eh,' ',0Fh,'R',01h,'a',02h,'l',03h
db 'f',04h,' ',05h,'B',06h,'r',07h,'o',08h,'w',09h
db 'n',0Ah,'!',0Bh ; no need to terminate...
msg1len dw $-msg1 ; let the assembler count 'em!
segment .text
mov ax, 3 ; reset video mode to 3 (cheesy CLS)
int 10h ; call bios video services
domore:
mov bp, msg1 ; point to string
mov cx, [msg1len] ; length of string - chars + attributes
shr cx, 1 ; div by two to get char-only len for the call
mov dh, 0Bh ; row
mov dl, 01Ah ; column
mov bh, 0 ; video page "usually" (?) zero
; don't care what BL is for this AL
mov ah, 13h ; write string in ES:BP at DH,DL (row,column)
mov al, 2 ; char, attr,... format - no cursor update
; 3 - char,attrib - update cursor
; 1 - attrib in BL - update cursor
; 0 - attrib in BL - no update
int 10h ; call video services (AT+,EGA+ ???)
; rather than alter the pallette, we just
mov bx, msg1 ; change the colors in the string, and
mov cx, [msg1len] ; reprint it (no cursor update :) ! )
shr cx, 1 ; number of colors
morecolors:
inc bx ; skip over character
mov al,[bx] ; get current color
inc al ; bump it
cmp al, 10h ; we only change low nibble - high nibble
jnz colorok ; is background (bit 7 set - FG blinks)
mov al, 1 ; we don't want color zero (black), or we
colorok: ; could just "or al,0Fh"
mov [bx], al ; stuff it back in the string
inc bx ; point to next character
loop morecolors ; do 'em all
mov cx, 2 ; BIOS is "slow", but we still
call DELAYCX ; need some delay
mov ah, 1 ; check keyboard status
int 16h
jz domore ; no key hit - do it again
mov ah, 0 ; get the key off the buffer
int 16h
; could clearscreen again here, but
exit: ; naw, let's leave it...
mov ah, 4Ch ; scram
int 21h
;----------------------------------------------------------
; twiddle thumbs for cx/18.2 seconds
DELAYCX
push ax
push bx
push ds
mov bx, 40h ; BIOS data segment
mov ds, bx
mov bx, 6Ch ; BIOS timer, 40:6C
mov ax, [bx]
add ax, cx
DelayLoop:
cmp ax, [bx] ; Is it the same?
jnc DelayLoop ; No, try again.
pop ds ; Restore registers and exit.
pop bx
pop ax
ret
;------------------------------------------------------------------