0

I am making a bootloader which prints 3 strings. I can successfully print those strings separated by lines in bochs but cannot do so when I use Rawrite to write the 512 byte bootloader to usb and boot it. It only prints the new lines. I even initialized the registers.

org 0x7c00
bits 16

cld

mov ax, 0
mov bx, 0
mov cx, 0
mov dx, 0

mov ds, ax
mov cs, ax
mov es, ax
mov ss, ax
mov sp, ax

jmp main

Print:
mov al, [bx]

cmp al, 0
je PrintD
mov ah, 0x0e
int 0x10
inc bx
jmp Print

PrintD:
ret

Println:
call Print

mov al, 10
int 0x10

mov al, 13
int 0x10

ret

main:

mov bx, HELLO_MSG

call Println

mov bx, GOODBYE

call Println

mov bx, THANKS

call Println

jmp $

HELLO_MSG: db "Hello World!",0

GOODBYE: db "Goodbye!",0

THANKS: db "Thank you for choosing Garg OS!",0

times 510 - ($-$$) db 0

dw 0xaa55

I am just a beginner. This question does not help me- Code works on bochs but does not on real computer, x86 real mode

Community
  • 1
  • 1
Arjav Garg
  • 33
  • 6
  • The comments to [that other question](http://stackoverflow.com/questions/36195242/code-works-on-bochs-but-does-not-on-real-computer-x86-real-mode) *should* have helped you. You aren't initializing the segment registers. See also tip #1 [here](http://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code/32705076#32705076). – Cody Gray - on strike Apr 24 '17 at 14:24
  • +Cody Gray so mov ax, 0 and mov ds, ax? The same for es ss and cs? – Arjav Garg Apr 24 '17 at 14:27
  • Still doesn't work. I have initialized sp with 0 also. It only prints the new lines. – Arjav Garg Apr 24 '17 at 14:31
  • Are you putting this on a USB drive when booting it on real hardware? Sorry I just reread your question, the answer is yes. That has its own set of issues including how the BIOS is set to handle USB drives (Floppy or HDD emulation) and depending on that you may need a Boot Parameter Block in your bootloader. – Michael Petch Apr 24 '17 at 14:37
  • Yes, using RawriteWin. It produced results before +Michael Petch – Arjav Garg Apr 24 '17 at 14:38
  • If you are seeing some output but not what you are expecting it is very likely the BIOS over wrote part of your code after it was loaded into memory (usually drive geometry data). I'd put a fake Boot Parameter Block into your bootloader to avoid that. I believe I have an answer for that - have to find it. – Michael Petch Apr 24 '17 at 14:41
  • When I said Boot Parameter Block I really meant BIOS Parameter block sorry (fingers faster than my remaining brain cell) – Michael Petch Apr 24 '17 at 14:44
  • I think there is some problem with the way I call my Print function or the print function itself because the newlines after the print are being printed. +Michael Petch – Arjav Garg Apr 24 '17 at 14:45
  • It is also possible part of your code has been clobbered with data that make it do the wrong thing. I would consider looking at this answer: http://stackoverflow.com/a/41919719/3857942 . It is written for GNU assembler but you can crate a similar structure in NASM. The question there may be similar to what is happening to you. – Michael Petch Apr 24 '17 at 14:47
  • is `mov cs,ax` correct way to set up `cs`? According to Internet docs (sorry to not crosscheck with official Intel docs) *"The MOV instruction cannot be used to load the CS register. Attempting to do so results in an invalid opcode exception (#UD). To load the CS register, use the far JMP, CALL, or RET instruction."* .. so I think you should do instead `jmp 0:main` (is this correct far jump syntax of nasm?) instead of `mov cs,ax`. (just use listing after compilation to verify correct machine code (far jump) was generated) – Ped7g Apr 24 '17 at 14:52
  • +Michael Petch nope. No luck. I added the BPB from here without the labels and jumped over it http://www.brokenthorn.com/Resources/OSDev4.html – Arjav Garg Apr 24 '17 at 15:00
  • `mov cs, ax` is a very bad idea . From the instruction set reference: _The MOV instruction cannot be used to load the CS register. Attempting to do so results in an invalid opcode excep-tion (#UD). To load the CS register, use the far JMP, CALL, or RET instruction._ – Michael Petch Apr 24 '17 at 15:08
  • That is done +Michael. – Arjav Garg Apr 24 '17 at 15:08
  • We have no idea what your code looks like and what you have done now. So it is very hard to know what you are doing. If you wish, at the bottom of your existing question (without removing what you have) add an **update** with the exact code you are trying now – Michael Petch Apr 24 '17 at 15:10
  • I also don't use rawrite on Windows, so one has to also assume you are correctly writing the boot sector onto your USB drive with it. – Michael Petch Apr 24 '17 at 15:18
  • Yes I am. You can see it in HxD – Arjav Garg Apr 24 '17 at 17:11
  • 1
    Initializing the stack to SS:SP = 0:0 is also a very bad idea! Normally you initialize the stack to SS:SP = 0:7BFE after booting or you even don't touch the SS and SP registers. – Martin Rosenau Apr 25 '17 at 12:27
  • @MartinRosenau : here is nothing wrong with doing the preferable SS:SP = 0:7C00 since the stack pointer is decremented by 2 first before data is placed there by a PUSH. 0x0000:0x0000 is not ideal but not as catastrophic as you might think. The first `PUSH will wrap the offset and begin writing at 0x0000:0xFFFE. That's safe as long as you don't overwrite that memory in your own code. If you ever read data into memory or need additional memory you'll want to set the stack since you don't want to clobber it. By setting your own you can avoid that situation. – Michael Petch Mar 15 '18 at 20:36

0 Answers0