Author Topic: print char to screen with int 0x10 interupt help  (Read 18355 times)

Offline annonymous

  • Jr. Member
  • *
  • Posts: 13
print char to screen with int 0x10 interupt help
« on: May 05, 2012, 01:09:57 AM »
Hey, y'all. I am attempting to print a character to the screen and not the terminal. I am having no luck though.

Here is my code:
Code: [Select]

[BITS 16]
[ORG 0xA000] ;Using ORG gives me an error

section .text

global _start

_start:

mov AL, 65
mov AH, 0x0E
mov BH, 0x00
mov BL, 0x07
int     10h

mov  AH, 1
mov  BH, 0
int          80h

What am i doing wrong? It produces a seg fault.

Im using Linux by the way. Thanks
« Last Edit: May 05, 2012, 01:28:47 AM by annonymous »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: print char to screen with int 0x10 interupt help
« Reply #1 on: May 05, 2012, 02:52:44 AM »
Ummm... it's pretty much wrong from beginning to end! I doubt if Linux will give you direct access to the screen. I doubt if you want 16-bit code. I can't imagine why you'd want org 0xA000. Bios interrupts, being 16-bit code, won't work from Linux (probably where the segfault occurs - I'm surprised Linux even attempts to run it!). Even your sys_exit, if that's what it's supposed to be, wants 1 in eax, not ah!

There are a couple of files in /dev that will let you write a character or character and attribute - similar to putting stuff to 0B800:xxxx direct to the screen in real mode - /dev/vcs0 and /dev/vcsa0 (and other numbers). Perhaps that would help you? There's an example in the "asmutils" package from http://asm.sf.net - "window.asm", IIRC.

I've got some code from "Richard Cooper" (not his real name, I don't think) which fiddles ports to do video. Pretty complicated, as I recall. I might be able to find that, if you think it'll help.

There are sys_vm86 and sys_vm86old that might allow you to use bios interrupts. I've never been able to make it work. There's a "LRMI" (Linux Real Mode Interface) library at sourceforge that might give a clue.

I think you're better off to use sys_write to print your character to the console/terminal. Why don't you want to do it that way?

Best,
Frank


Offline annonymous

  • Jr. Member
  • *
  • Posts: 13
Re: print char to screen with int 0x10 interupt help
« Reply #2 on: May 05, 2012, 04:27:19 AM »
Quote
Ummm... it's pretty much wrong from beginning to end!
I pulled an example off of the net and tweaked it some. Sorry i just started coding in ASM no more than 6 months ago. I juggle between 2 or 3 more languages. So i do not spend a ton of time in NASM, it is my favorite though!

 
Quote
I doubt if Linux will give you direct access to the screen.
WHy wouldn't it? There is a cursor and images being printed to my screen at this very moment.

Quote
I doubt if you want 16-bit code.
The example was in 16-bit mode.

Quote
I can't imagine why you'd want org 0xA000. Bios interrupts, being 16-bit code, won't work from Linux (probably where the segfault occurs - I'm surprised Linux even attempts to run it!). Even your sys_exit, if that's what it's supposed to be, wants 1 in eax, not ah!
Quote
yes, that's my sys_exit. Didn't know that it must be placed in EAX. I was under the assumption that as long as is was an accumulator register, i was good.

Quote
There are a couple of files in /dev that will let you write a character or character and attribute - similar to putting stuff to 0B800:xxxx direct to the screen in real mode - /dev/vcs0 and /dev/vcsa0 (and other numbers). Perhaps that would help you? There's an example in the "asmutils" package from http://asm.sf.net - "window.asm", IIRC.

I've got some code from "Richard Cooper" (not his real name, I don't think) which fiddles ports to do video. Pretty complicated, as I recall. I might be able to find that, if you think it'll help.

There are sys_vm86 and sys_vm86old that might allow you to use bios interrupts. I've never been able to make it work. There's a "LRMI" (Linux Real Mode Interface) library at sourceforge that might give a clue.
I have not the slightest of any of that meant lol

Quote
I think you're better off to use sys_write to print your character to the console/terminal. Why don't you want to do it that way?
I have. I have wrote 2 programs so far. Printing strings to stdout. Two, request and take in user input and display what they entered to stdout.

I just wanted to try to print a random character to the screen with everything else still in tact. I seen a sample snippet somewhere but cannot remember where i found it. It was a money symbol.
 

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: print char to screen with int 0x10 interupt help
« Reply #3 on: May 05, 2012, 08:09:02 PM »
I pulled an example off of the net and tweaked it some. Sorry i just started coding in ASM no more than 6 months ago. I juggle between 2 or 3 more languages. So i do not spend a ton of time in NASM, it is my favorite though!

Could you post the example without modifications?

Quote
I doubt if Linux will give you direct access to the screen.
WHy wouldn't it? There is a cursor and images being printed to my screen at this very moment.

In 32-bit user-mode, you're not allowed access to directly read/write from hardware. To do this, you'll need to write a kernel module which is ran with Ring-0 access (not for the faint of heart).

Quote
I doubt if you want 16-bit code.
The example was in 16-bit mode.

The example was probably for DOS, not Linux. Linux (afaik) only supports 32-bit or 64-bit systems.

Quote
I can't imagine why you'd want org 0xA000. Bios interrupts, being 16-bit code, won't work from Linux (probably where the segfault occurs - I'm surprised Linux even attempts to run it!). Even your sys_exit, if that's what it's supposed to be, wants 1 in eax, not ah!
yes, that's my sys_exit. Didn't know that it must be placed in EAX. I was under the assumption that as long as is was an accumulator register, i was good.

It doesn't work in AH because AH is the top 8 bits of of the AX register (which is the lower 16-bits of the eax register). Setting AL would work as long as EAX is cleared first, but it'd be just as easy to set EAX directly.

Frank:
Quote
I can't imagine why you'd want org 0xA000.

I believe he just read some tutorial which said that video memory was located at 0xA000 (when in 256 VGA color mode) and made an ASSumption that he should ORG there.

Regards,
Bryant

About Bryant Keller
bkeller@about.me

Offline annonymous

  • Jr. Member
  • *
  • Posts: 13
Re: print char to screen with int 0x10 interupt help
« Reply #4 on: May 07, 2012, 02:24:29 AM »
Quote
Could you post the example without modifications?
Here is the site i was referencing ---> http://viralpatel.net/taj/tutorial/hello_world_bootloader.php

Quote
In 32-bit user-mode, you're not allowed access to directly read/write from hardware. To do this, you'll need to write a kernel module which is ran with Ring-0 access (not for the faint of heart).
Sounds extremely complicated! Especially for a beginner such as myself.

Quote
The example was probably for DOS, not Linux. Linux (afaik) only supports 32-bit or 64-bit systems.
The tutorial is aimed towards Linux but has instructions for windows as well.

Quote
It doesn't work in AH because AH is the top 8 bits of of the AX register(which is the lower 16-bits of the eax register). Setting AL would work as long as EAX is cleared first, but it'd be just as easy to set EAX directly.

Quote
Frank:
Quote
I can't imagine why you'd want org 0xA000.

I believe he just read some tutorial which said that video memory was located at 0xA000 (when in 256 VGA color mode) and made an ---> ASSumption <--- that he should ORG there.

Regards,
Bryant

Gee, thanks! lol But Bryant was right for everything except the "a**"umption. I was given a link by someone and they explained the above.

I am just going to move on and try something more my level... BEGINNER. Thanks

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: print char to screen with int 0x10 interupt help
« Reply #5 on: May 07, 2012, 04:06:18 AM »
Okay... your example is for a bootsector. You can write it, assemble it, and copy it to a floppy disk from Linux, but it isn't intended to run under Linux - the CPU is still in 16-bit mode at bootup.

As to "direct access to screen"... Suppose you write, or just imagine, a program that prints characters continuously - put a delay in it if you like, but just keep printing characters. Set it going and switch to another console (or other process). Do you still see the characters? Would you want to? Things are different in a multi-tasking, multi-user OS! You really don't want access to the screen until it's "your turn".

We can do something roughly like int 10h/0Eh - print whatever character is in al...

Code: [Select]
; nasm -f elf32 myprog.asm (or just "-f elf")
; ld -o myprog myprog.o (-melf_i386 for 64-bit systems)

global _start

section .data
    dollar db '$'
    cent db 162
    pound db 163
    yen db 165

section .text
_start:
    mov al, [dollar]
    call putc
    mov al, 10
    call putc

    mov al, [cent]
    call putc
    mov al, 10
    call putc

    mov al, [pound]
    call putc
    mov al, 10
    call putc
   
    mov al, [yen]
    call putc
    mov al, 10
    call putc
   
    mov eax, 1
    int 80h

putc:
; prints the character in al
    push edx ; save caller's regs
    push ecx
    push ebx
    push eax ; doubles as a buffer to print from

    mov edx, 1 ; print just one character
    mov ecx, esp ; our "buffer" (on the stack)
    mov ebx, 1 ; stdout
    mov eax, 4  ; sys_write
    int 80h

    pop eax
    pop ebx
    pop ecx
    pop edx
    ret

That prints a few "money symbols", found by trial and error. Works on my system, may not work on yours. I don't think it's really satisfactory. I suspect maybe we need to learn unicode!

I think there are alternate character-sets available - I forget what I've been told about 'em... except that if you mess up your display, typing "reset" (even if you don't see those characters) may restore it.

There are BIOS interrupts that will allow you to "hand draw" a character - that is, provide data to "draw" an arbitrary character not otherwise available. I suspect there may be similar abilities for Linux, but I don't know how to do it Lots to learn!

Best,
Frank