2

This small piece of code works fine on bochs 2.6, but doesn't seem to work on 'real' computers (I've tried several of them). It seems like lodsb is causing the problem, since it worked fine, when I did hello world by printing the string "manually" character by character.

.code16
.text
.globl _start
_start:

    movw $0, %ax
    jmp main

### DATA AND BUFFERS ###
welcome:
    .asciz "welcome"

main:
    movw $welcome, %si
    call print_string

hang:
    jmp hang

print_string:
    lodsb

    cmp $0, %al
    je done

    mov $0x0e, %ah
    int $0x10
    jmp print_string

done:
    ret


. = _start + 510
.byte 0x55
.byte 0xaa

Since I don't have a debugger on my 'real' computer I can't quite figure out what is the problem and restarting computer so many times becomes really frustrating. Can the problem be with segment registers?

Problem solved: Issue was with the direction flag, that unlike bochs was set backwards when bios jumped on my code. For more details and suggestions to avoid further problems see the answers below.

  • 2
    You should see my General Bootloader Tips in this [Stackoverflow answer](http://stackoverflow.com/a/32705076/3857942). You don't show your linking step but I assume you are at least using `-Ttext=0x7c00` with _LD_. If your origin point is 0x7c00 then you need to explicitly set _DS_ to zero when your bootloader starts. You should also set a stack and use _CLD_ to set the direction flag forward for LODSB (and related string instructions). Your code makes a number of assumptions that may not hold true for your real hardware. – Michael Petch Mar 24 '16 at 08:46
  • On top of my first comment you should also set _BH_ to zero to ensure you are writing your text to page 0 (the default page in text mode) when you call [int 10h/ah=0eh](http://www.ctyme.com/intr/rb-0106.htm) – Michael Petch Mar 24 '16 at 08:49
  • 2
    Most likely the reason your real hardware doesn't work (but is okay in character by character mode) is because the _DS_ segment that is set before your bootloader launches is different than what Bochs uses. _LODSB_ requires the _DS_ register to be set properly. – Michael Petch Mar 24 '16 at 08:54
  • 2
    @MichaelPetch Thanks. Problem was with the direction flag. Great post by the way, taught me a lot. From now on I'll initialize my segment registers, but in this case that was not a problem, since move instruction when fetching data from memory worked fine and move uses DS as well, as far as I know. Thank you once again – Nagavi Bindzuriani Mar 24 '16 at 10:19
  • 1
    Your `movw $0, %ax` and `movw $welcome, %si` instructions don't use DS. The source operands in both these instructions are immediates so the values being loaded into the registers are encoded as part of the instruction. Instructions are fetched using CS, so DS isn't used. In fact LODSB is the only instruction in your code that uses DS. – Ross Ridge Mar 24 '16 at 18:05

0 Answers0