Page 1 of 1

Problem with displaying character on screen

Posted: Sat May 17, 2008 10:18 am
by shogun1234
I am newbie to learn how to develop OS and follow the tutorial at http://linuxgazette.net/issue77/krishnakumar.html, trying to covert code from as86 to AT&T. The problem is the character (i.e. A) does not display on the screen. Below is what I coded.

Code: Select all

        .global _start
_start:
        movl  $0xb800, %eax
        movl  %eax, %es
        movl  $0x41, (0)
        movl  $0x1f, (1)
loop:
        jmp   loop
This code worked when using as86 version.

In addition, the way to run that programme is to create an os in virtualbox and launch the os by pointing the boot floppy to generated programme, e.g. bin.img. This procedure works whilst the code is exactly the same as what is in tutorial, but does not work when programme converted to AT&T syntax version.

I think the problem should be from where I move characters (0x41 & 0x1f) to the place the display register located (i.e. 0xb800); because I am not familiar with assembly. There should have something I did was wrong but am not aware of it at all.

Hope someone can give me advice,

I appreciate it.

Thank you very much,
env: GNU/Linux kernel 2.6.20/ Debian lenny testing/ gcc 4.2.2-4/ as 2.18/ virtualbox 1.5.6

Posted: Sat May 17, 2008 10:33 am
by svdmeer
AS assembly code really sucks. I don't understand why they assembly that way..

Back on topic..

I think your code has to be this way:

Code: Select all

    .global _start 
_start: 
        mov ax,0xb800
        mov es,ax
        mov byte [es:0],0x41   ; character ('A')
        mov byte [es:1],0x1f    ; color (white on blue)
loop: 
        jmp loop
Which assembler do you use?
With NASM .global _start and _start: are not needed.

Assembling using NASM, you have to add the lines "CPU 8086" and "BITS 16" at the beginning of your source, and at the end:

Code: Select all

                times (512-2)+$$-$ db 0 ; Fill with zeroes
                dw 0xAA55               ; Magic ID
Assembly with "nasm -f bin -o sector.bin sector.asm".

You have a 512-byte file. Write to floppy-disk with "dd if=sector.bin of=/dev/fd0". You won't need a seperate C-program to write the bootsector to floppy. Linux/Unix have better tools.

...........; because I am not familiar with assembly.
You first have to learn assembly. Without it, you can never write an OS by yourself (or without any other developer doing the assembly-work)

Posted: Sun May 18, 2008 4:12 am
by shogun1234
svdmeer wrote:AS assembly code really sucks. I don't understand why they assembly that way..
Why do you think that assembly is not good? (Sorry I English is not good)
Is it because assembly itself or simply because that document is not a good tutorial? I am just curious.
Back on topic..

I think your code has to be this way:

Code: Select all

    .global _start 
_start: 
        mov ax,0xb800
        mov es,ax
        mov byte [es:0],0x41   ; character ('A')
        mov byte [es:1],0x1f    ; color (white on blue)
loop: 
        jmp loop
Which assembler do you use?
I use 'as' assembler that is shipped with GNU/ Linux distribution.
With NASM .global _start and _start: are not needed.

Assembling using NASM, you have to add the lines "CPU 8086" and "BITS 16" at the beginning of your source, and at the end:

Code: Select all

                times (512-2)+$$-$ db 0 ; Fill with zeroes
                dw 0xAA55               ; Magic ID

Assembly with "nasm -f bin -o sector.bin sector.asm".

You have a 512-byte file. Write to floppy-disk with "dd if=sector.bin of=/dev/fd0". You won't need a seperate C-program to write the bootsector to floppy. Linux/Unix have better tools.

...........; because I am not familiar with assembly.
You first have to learn assembly. Without it, you can never write an OS by yourself (or without any other developer doing the assembly-work)
You are right. So I start to learn by real case, though it is tedious step.

Thanks your help,

I appreciate it.

Posted: Sun May 18, 2008 9:44 am
by svdmeer
Why do you think that assembly is not good? (Sorry I English is not good)
Is it because assembly itself or simply because that document is not a good tutorial? I am just curious.
It's the assembly itself. The way AS writes assembly-language is non-standard. Besides AS uses many symbols in the lines like %. It's hard to read (and to learn).
Every good x86-assembly uses the standard Intel notation. AS reverses arguments, e.g. MOV AX,1 is with AS-notation MOV 1,AX. Everyone knows you can't give a constant a register-value, but with to registers it becomes really confusing. MOV AX,BX and MOV BX,AX are really different.

I don't think the tutorial you used is good for beginners. For two reasons. One: It's incomplete. It only creates bootsectorcode for putting something on the screen. It's a bootsector-tutorial, but no OS-development tutorial. Reason two: Complicated for beginners with a C-program for writing the bootsector and the use of AS.

I like this tutorial: http://www.brokenthorn.com/Resources/OSDevIndex.html

In this tutorial Windows is used, but all the tools are on Linux.
I use 'as' assembler that is shipped with GNU/ Linux distribution.
I recommend NASM. It's easy and flexible. Perfect to start with, without worrying about additional rules and switches from the assembler itself. Some people here use FASM, that's also ok. Keep it simple when you begin.

Posted: Sun May 18, 2008 2:25 pm
by AJ
Hi,

Just a bit of a plea to people on the board not let this turn in to a syntax flame war. Let me explain...
svdmeer wrote:Every good x86-assembly uses the standard Intel notation. AS reverses arguments...
The way AS writes assembly-language is non-standard.
Wrong. There are two common standards about. Intel syntax (mov dest, src) and AT&T syntax (mov src, dest) which have a few other differences in addition to the operand order. Which version you use is entirely down to personal preference.

I prefer Intel Syntax because it is what I am used to. Many on this board find AT&T Syntax more natural. By default, GCC and G++ output to AT&T syntax and use AT&T for inline assembly. This can easily be switched to Intel Syntax inline or at the command prompt. If you want to learn by reading other people's code, be able to read both types. You will find that some people get very protective about their chosen syntax (like they do about their chosen OS or HLL).

Obviously, you can code in whatever you find more comfortable.

Cheers,
Adam

Re: Problem with displaying character on screen

Posted: Tue May 20, 2008 8:49 am
by jal
shogun1234 wrote:Hope someone can give me advice
1) "movl $0xb800, %eax" "movl %eax, %es" - I really doubt this even compiles. es is a 16 bit register, eax is a 32 bit register. movl with %es as destination should trigger a compiler error!
2) "movl $0x41, (0)" "movl $0x1f, (1)" - you reference memory in the ds segment here, not the es segment. So this doesn't work, obviously.

I have the feeling you know very little about assembly and the Intel CPU architecture. That's not good if you want to start OS development. So the best advise I can give you is to go back to square one and first develop the required skills.


JAL

Posted: Wed May 21, 2008 12:40 am
by jinksys
This is the code he is trying to translate from AS86:

Code: Select all

entry start
start:
      mov ax,#0xb800
      mov es,ax
      seg es
      mov [0],#0x41
      seg es
      mov [1],#0x1f
loop1: jmp loop1
Here it is in good ol' Gas At&t Syntax:

Code: Select all

.code16
.global _start
_start:
      movw  $0xb800, %ax
      movw  %ax, %es
      movb  $0x41, %es:0
      movb  $0x1f, %es:1
loop1:
      jmp loop1

I am not familiar with assembly.
That might be a problem :roll: Good Luck!