Bugy Code
Bugy Code
Could you please tell me what's wrong with this code? I just can't find it out. It loads OK(trust me, I testet it with a nother function), but it won't display a string.
code
[BITS 16]
[ORG 0x2C00]
cli
mov ax,0xFFFF
mov sp,ax
mov ax,0x2C00
mov ss,ax
xor ax,ax
mov ds,ax
sti
jmp startrealk
printstringk:
mov ah,13
mov al,0x01
mov bh,0x00
mov bl,0x07
int 0x10
ret
startrealk:
mov es,[message1]
mov bp,message1
mov cx,0x3
call printstringk
message1 db 'Hi',0
code end
code
[BITS 16]
[ORG 0x2C00]
cli
mov ax,0xFFFF
mov sp,ax
mov ax,0x2C00
mov ss,ax
xor ax,ax
mov ds,ax
sti
jmp startrealk
printstringk:
mov ah,13
mov al,0x01
mov bh,0x00
mov bl,0x07
int 0x10
ret
startrealk:
mov es,[message1]
mov bp,message1
mov cx,0x3
call printstringk
message1 db 'Hi',0
code end
Re:Bugy Code
In the absence of other information, I'm assuming that this is a boot loader; if it isn't, then we'll need more context before we can help you with it.
First off, your origin should be 0x7C00, not 0x2C00. While the code may load correctly, the addresses will be all wrong as a result.
Second, you have to keep in mind that while ORG sets the segment offset, [tt]mov ss, ax[/tt] sets the segment base. In this case,
[ORG 0x7C00] == 0000:7C00 == 07C00:0000
whereas
== 7C00:0000
If you want to set the stack and data segment bases to match the code segment, the best solution is to use
For that matter, since not all BIOSes follow the standards, it would be wise to reset the code segment and offest explicitly at the beginning of the code, like this:
Third, There's no real ending to your code; after printstringk returns, the program just sort of walks off then end of the code. You'll want to add some kind of busy loop, like so:
Where the dollar sign is a special directive meaning 'the current address'.
Finally, you don't include the Boot Signature, a special word-sized indicator (0x55AA) at the end of the boot block which marks it as valid. To add this, you need to pad out the data to 2 bytes before the end of the book block; since the boot block is 512 bytes in length, you would need to use:
Where, '$$' is a directive meaning 'the beginning of the program'. This is followed by the boot signature itself:
Oh, and BTW, the tags for starting and ending a block of code in YaBBcode are [ code ] and [ /code ], without the spaces. HTH.
First off, your origin should be 0x7C00, not 0x2C00. While the code may load correctly, the addresses will be all wrong as a result.
Second, you have to keep in mind that while ORG sets the segment offset, [tt]mov ss, ax[/tt] sets the segment base. In this case,
[ORG 0x7C00] == 0000:7C00 == 07C00:0000
whereas
Code: Select all
mov ax, 0x7C00
mov SS, ax
If you want to set the stack and data segment bases to match the code segment, the best solution is to use
Code: Select all
mov ax, cs
mov ss, ax
mov ds, ax
Code: Select all
entry: jmp far [0000:start]
start:
cli
...
Code: Select all
jmp short $
Finally, you don't include the Boot Signature, a special word-sized indicator (0x55AA) at the end of the boot block which marks it as valid. To add this, you need to pad out the data to 2 bytes before the end of the book block; since the boot block is 512 bytes in length, you would need to use:
Code: Select all
(510 - $ - $$) times db 0
Code: Select all
bootsig db 0x55AA
Oh, and BTW, the tags for starting and ending a block of code in YaBBcode are [ code ] and [ /code ], without the spaces. HTH.
Re:Bugy Code
is this bootloader code? I'm wondering about the org 2c00. If this is bootloader code
will have problems with the offset. Also, what exactly doesn't work? What happens? Becuase after you return from "call printstringk" it seems like there would be invalid code there. Also, you never initialize dh and dl before the int10 to specify the row and column. If this is bootloader code, not only is dx not guaranteed to be 0, but iirc dl will be the drive that was booted.
Code: Select all
mov es,[message1]
mov bp,message1
will have problems with the offset. Also, what exactly doesn't work? What happens? Becuase after you return from "call printstringk" it seems like there would be invalid code there. Also, you never initialize dh and dl before the int10 to specify the row and column. If this is bootloader code, not only is dx not guaranteed to be 0, but iirc dl will be the drive that was booted.
Re:Bugy Code
No, it isn`t the bootloader. It is loaded at 2c00. But thanks, i`ll try that out right away.
Re:Bugy Code
In that case, it may help if you could answer some questions:
[*] How is the code being loaded, and from what? I am assuming that, since it is not the bootloader itself, it is the kernel or second stage loaded by the bootloader (presumably the former, since the function names end in 'k' - I'd missed that before).
[*] How are you transferring control to the program, with a jump or a call, and was it NEAR or FAR?
[*] What is the full address transferred to - 0000:2C00, or 02C0:0000, or 2C00:0000? Is there a particular reason for that location?
[*] If this is the kernel, are you certain that you want to have the stack in the same segment as the code and data?
Hopefully, this will help us with your problems.
[*] How is the code being loaded, and from what? I am assuming that, since it is not the bootloader itself, it is the kernel or second stage loaded by the bootloader (presumably the former, since the function names end in 'k' - I'd missed that before).
[*] How are you transferring control to the program, with a jump or a call, and was it NEAR or FAR?
[*] What is the full address transferred to - 0000:2C00, or 02C0:0000, or 2C00:0000? Is there a particular reason for that location?
[*] If this is the kernel, are you certain that you want to have the stack in the same segment as the code and data?
Hopefully, this will help us with your problems.
Re:Bugy Code
First, I'D like to thank you guys for giving so mutch atention to a newbee like me. Now to your questions.
It is the kernel. It is loaded with: jmp 2000:0000.
I chose this location, because I don`t need much space for the kernel(only 8k) and it is an empty part of memory.
It is the kernel. It is loaded with: jmp 2000:0000.
I chose this location, because I don`t need much space for the kernel(only 8k) and it is an empty part of memory.
Re:Bugy Code
And I don`t have to have the stack in this segment. I only thought it is the only way of doing it.
Re:Bugy Code
Ah, then there is part of your problem: in real mode, the origin statement only applies to the segment offset, not the segment base or the linear address. Since your offset is 0x0000, then you need your origin to be 0x0000 as well.Yann Kiraly wrote: First, I'D like to thank you guys for giving so mutch atention to a newbee like me. Now to your questions.
It is the kernel. It is loaded with: jmp 2000:0000.
I chose this location, because I don`t need much space for the kernel(only 8k) and it is an empty part of memory.
If you need a deeper explanation of segment arithmetic, see Perica Senjak's real mode addressing tutorial, and review these threads:
Replies #11 and #23
Reply #24
Reply #4
Reply #2
Don't worry too much if it seems confusing right now; segmented addressing is one of the most difficult aspects of the x86 architecture to understand. It only gets worse in protected mode, I'm afraid, though there are some workarounds there that make things easier. In real mode, no such shortcut is available, so you really do need to undertand it.
Re:Bugy Code
I took a different aproach loading my (with your help corrected) Kernel from the FAT filesystem.Thanks. And now I wanted to ask how a kernel and bootloader can be written to an unformated floppy using Windows with rawwrite or Linux?