News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Set CS in real mode

Started by kendfrey, October 28, 2011, 07:25:00 PM

Previous topic - Next topic

kendfrey

I am having trouble figuring out how to set the CS register. I am writing code for a boot sector, so this is in real mode. I simply want to set CS to 0 without interrupting program flow. Is there a way to do this?
I wasn't sure if this belongs in 16-bit forum or not, so be patient.

redskull

Try moving it from a general purpose register (i.e. set ax to zero, then mov ax to cs).  Though beware, new members who ask basic, trivial questions regarding implementations of highly advanced topics are generally treated with disdain and distrust.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

kendfrey

mov ax, 0000h
mov cs, ax

Sorry, didn't work. Bochs gives me:
MOV_EwSw: can't use this segment register 1

dedndave

the easy way to do a segment translation is to use a FAR RET
when you change CS, you have to make sure that IP points to valid code
FAR RET (RETF) changes both at the same time
it can also be done with a FAR JMP, but it isn't as pretty

but, CS is already 0 when the machine BIOS transfers control to the read-into-memory boot sector at 0000:7C00

kendfrey

Quote from: dedndave on October 28, 2011, 08:29:03 PM
but, CS is already 0 when the machine transfers control to the read-into-memory boot sector at 0000:7C00

Always? I read that some BIOS's run the boot sector at 07c0:0000h. (I don't remember where, but I read it!)

dedndave

i have never encountered such a machine, but i see that text on wikipedia
1) wikipedia is a terrible place to get information on computer code
2) who knows - they may be right - lol
a better place to ask would be the OsDev forum
http://wiki.osdev.org/Main_Page
http://forum.osdev.org/
those guys write boot sectors in their sleep   :P

ps - if a computer boots at 07C0:0000, i would have to say that it is not IBM compatible

kendfrey

It sounds like not booting from 07c0:0000 is bad enough that it need not be supported. Maybe I will forget about setting CS. Quick question: are DS and ES properly set?
I don't think it would help a whole lot to go to OSdev, since I was sent here from there, and it seems that the people here are nicer than the OSdev people when it comes to this kind of thing.

dedndave

as i recall, DS is set to the BIOS data segment (0040)

at any rate - if those guys are impolite, just ignore them - lol
still, the material available in that forum is substantial, and may be accessed by using the search tool

this thread actually belongs in the 16-bit sub-forum
i am sure bogdan will move it there, too - lol
if you look in that forum, you will find some boot code

here is a link that has some info
http://www.nondot.org/~sabre/os/articles/TheBootProcess/

Ralf Brown's Interrupt List also has some info

let me look at some of my old books.....

kendfrey

OK, I will put that info to use. Thanks a bunch.
BTW I love your sig. Gives me an idea for a new OS.  :wink

dedndave

well - it looks like ES and DS are set to 0000 (reading IBM AT BIOS code)
however, don't trust that ES will be 0, unless you are writing floppy-only code   :P
if you boot from a USB device, i think ES:BX points to a descriptor table (maybe it's ES:DI)

MichaelW

You cannot set CS with MOV or POP, you must use a FAR JMP, CALL, or RET (or one of several other similar, and needlessly complex, methods), and given this you cannot set CS without altering the program flow.

The segment-offset addresses 0000:7C00 and 7C0:0000 resolve to the same physical address. The BIOS will load the boot sector at that address and transfer execution to it, and this transfer will set CS.

eschew obfuscation

Rockphorr

Quote from: MichaelW on October 29, 2011, 05:58:16 AM
You cannot set CS with MOV or POP, you must use a FAR JMP, CALL, or RET (or one of several other similar, and needlessly complex, methods), and given this you cannot set CS without altering the program flow.

The segment-offset addresses 0000:7C00 and 7C0:0000 resolve to the same physical address. The BIOS will load the boot sector at that address and transfer execution to it, and this transfer will set CS.



yes it's right


your segment at 0
db 7C00 dup (?)
for_jump LABEL FAR
your ends

.code
jmp far ptr for_jump

; after you got cs=0 ip=7C00




Strike while the iron is hot - Бей утюгом, пока он горячий