i've copied this code from net but this is not working. Only blank output. can anyone help. i'm new to assembly.

[ORG 7C00h]                     ; This is where BIOS put me

; ---------------------------------------------------------
; Main program
; ---------------------------------------------------------

        mov si, msg             ; Print message
        call putstr

hang:   jmp hang                ; Hang!

; ---------------------------------------------------------
; Functions and variables used by our bootstrap
; ----------------------------------------------------------

msg     db 'Hello Cyberspace!', 0

; Print a 0-terminated string on the screen
putstr:
        lodsb                   ; AL = [DS:SI]
        or al,al                ; Set zero flag if al=0
        jz .done                ; Jump to .done if zero flag is set
        mov ah,0x0E             ; Video function 0Eh
        mov bx,0x0007           ; Color
        int 0x10
        jmp putstr              ; Load characters until AL=0
.done:
        retn

times 512-($-$$)-2 db 0
        dw 0AA55h

as far as i think lodsb does not advance the cursor but i wrote code for cursor advancemnt but failed.

Thanks

Recommended Answers

All 22 Replies

You're working in 16-bit RealMode but why is your origin at 7c00h ?


lodsb is equivalent to

;16-bit
mov al,ds:[si]
inc si

;32-bit
mov al,ds:[esi]
inc esi

I don't see a problem but you are using Video Interrupt 10h, command 0Eh which ah=command, al=character. There is no color as its TTY (Raw ASCII text).

I think you're trying to write character and attribute which is command 09h
al=char
ah=command
bl=attribute
bh=page number
cx=# of times to write char.

Only one comment for you codeguru_2009: please put the code highlighting in your code, using this tags: [ code=asm ] ... [ /code=asm ], without spaces, it's just to for the best comprehension of the code.

Thanks!

His origin is at 7C00h because the BIOS bootstrap
will load the first sector of a drive containing a valid boot sector
at physical address 07C00h and will jump to it
loading CS with 0 and IP with 7C00h.

I added this to quickly boot your code with Bochs:

times 1474560 - ($ - $$) db 0

The code worked.
Your problem most likely is how you wrote it out to the disk.
The 512-byte image has to be written to cylinder 0,
head 0,sector 1 - the very beginning of the drive.

I've found no way to work this code. I'm using intel 865 motherboard and intel p4 2.8GHZ processor(HT support). I'm using nasm to compile and build .bin file. Using dd command to write to floppy disk.
I'm able to print single character at boot time but not the whole string.
Me still searching for clue. Any help will be greatly appreciated.

You could try initialising the ds register with a value of zero. It might be a good idea to set up a stack as well.

cli
xor ax,ax
mov ds,ax
mov ss,ax
mov sp, 0x7c00

Using dd command to write to floppy disk.

Have you tried any other third party file utilities?

And did you analyze the output with a hexeditor to check if everything went right?

I'm using dd only because my os is centos. Also i've tried partcopy but the result is same.
Can anyone pls try at their system(intel p4 users) and give the complete code.

org 0x7c00

cli                                              ;disable hardware interrupts
cld                                             ;clear direction flag
xor ax,ax                                   ;zero out ax
mov ds,ax                                 ;initialise data segment
mov ss,ax                                 ;initialise stack segment
mov sp, 0x7c00                        ;point sp at memory available for stack
mov si, msg                              ;ds:si -> message
call putstr                                 ;print message
hang:                                      
jmp hang                                  ;loop forever

msg     db 'Hello Cyberspace!', 0

putstr:
lodsb                                        ;load next character
or al,al                                      ;end of string?
 jz finish                                    ;exit loop if so
mov bx, 7                                  ;page = 0, attribute = 7
mov ah, 0xe                              ;print character function
int 0x10                                    ;print character
jmp putstr                                ;get next character

finish:
retn                                         ;return to caller

I'm not going to mess about creating a boot diskette, but I can see no reason why the above shouldn't work.

Are you clobberng your Segment register on purpose?

xor ax,ax                                   ;zero out ax
mov ds,ax                                 ;initialise data segment
mov ss,ax

this should be more like

mov ax,cs
mov ds,ax
mov ss,ax

Are you clobberng your Segment register on purpose?

I'm not clobbering anything. The boot sector always gets loaded at an absolute address of 7c00h, which means that the ds register must contain zero if the code is org'd at 7c00h.

Okay then.

Does your assembler understand C defines?

mov sp, 0x7c00

0x7c00 is a C definition.
0x10

Assemblers typically are looking for 07c00h
10h

Okay then.

Does your assembler understand C defines?

mov sp, 0x7c00

0x7c00 is a C definition.
0x10

Assemblers typically are looking for 07c00h
10h

Since I use MASM it recognises 7c00h, but if I used NASM it would recognise 0x7c00.

You were using C definitions in the posted code.

Examine your CS register and IP register.
What are their hex values when you first begin the code?

As an experiment replace your

lodsb                   ; AL = [DS:SI]

with

mov al,cs:[si]
   inc si

It'll then force the string load from the code segment!

You were using C definitions in the posted code.

I was using the syntax used by C and some assemblers.

Examine your CS register and IP register.
What are their hex values when you first begin the code?

In the case of a boot sector cs=0 and ip=7c00h (always).

Everything looks correct but I still think its a Segment:Offset issue.

Initialize your Graphics card Page#0 column 0, row 0. Before doing anything.

And try writing your ASCII letters directly into the text frame buffer.

mov ax,0b800h
 mov es,ax
 xor edi,edi

 mov es:[edi],al
 inc  edi
 inc  edi

It's been a while, but I think this is right.
Upon execution of the bootloader
CS,DS,ES will be zero,
And there is a 512-byte stack allocated by the BIOS.
SS (points where?) SP ?
I do not know if interrupts are disabled.

Has anyone else tested this bootloader?
Could it be because of this guys hardware configuration?

It's been a while, but I think this is right.
Upon execution of the bootloader
CS,DS,ES will be zero,
And there is a 512-byte stack allocated by the BIOS.
SS (points where?) SP ?
I do not know if interrupts are disabled.

Has anyone else tested this bootloader?
Could it be because of this guys hardware configuration?

He says that he can print the first character. I suppose it is possible that the direction flag is set when the boot sector gets control, so instead of pointing to the e after the H has been printed, it points to??? Solution: clear the direction flag (as above).

It is difficult to see how the hardware configuration can be responsible, assuming that it is running on a PC. The 6845 will have been set up by the bios so that messages like "Not a System Disk" can be displayed.

I haven't got a floppy drive fitted to my computer, so I can't test it.

Don't use the LODSB STOSB they aren't cost effective on short runs on newer processors. Do the mov, and inc yourself!

Thanks alot mathematician. your code is working fine on my system. I will compare it with my code and see what's the fault. Thanks once again!

I'll have to think about this when testing a boot loader
on the actual hardware instead of an emulator.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.