Author Topic: help:using bios interrupt  (Read 33772 times)

Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
help:using bios interrupt
« on: July 14, 2010, 03:54:27 PM »
hello there.. i tried a little code for hello world like
Code: [Select]
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???

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: help:using bios interrupt
« Reply #1 on: July 14, 2010, 06:06:45 PM »
-----> Int 10/AH=0Eh @ RBIL <-----

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #2 on: July 14, 2010, 07:42:32 PM »
I'll bet a nickle Ralf won't help him.

Where's your code loaded? (origin) Where's ds?

Best,
Frank


Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
Re: help:using bios interrupt
« Reply #3 on: July 15, 2010, 01:01:32 AM »
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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #4 on: July 15, 2010, 04:00:39 AM »
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


Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
Re: help:using bios interrupt
« Reply #5 on: July 15, 2010, 04:29:45 AM »
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

Code: [Select]
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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #6 on: July 15, 2010, 06:07:55 AM »
Code: [Select]
%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


Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
Re: help:using bios interrupt
« Reply #7 on: July 15, 2010, 01:23:24 PM »
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

Code: [Select]
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

Code: [Select]
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,

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #8 on: July 15, 2010, 04:23:09 PM »
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.

Code: [Select]
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"...

Code: [Select]
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


Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
Re: help:using bios interrupt
« Reply #9 on: July 16, 2010, 04:50:30 AM »
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...
Code: [Select]
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

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #10 on: July 16, 2010, 07:21:45 AM »
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


Offline bunkdeath

  • Jr. Member
  • *
  • Posts: 6
Re: help:using bios interrupt
« Reply #11 on: July 16, 2010, 03:31:22 PM »
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

Offline pleasent_4445

  • New Member
  • Posts: 1
Re: help:using bios interrupt
« Reply #12 on: January 16, 2011, 04:05:55 AM »
[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 $

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: help:using bios interrupt
« Reply #13 on: January 16, 2011, 06:59:00 AM »
Kewl!

Where's the bios interrupt?

Why:

Code: [Select]
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:

Code: [Select]
xor cx, cx

? Won't hurt.

Why:

Code: [Select]
jmp $

? We usually try to NOT hang the machine...

Here's a different bios interrupt:

Code: [Select]
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
;------------------------------------------------------------------