Here's someone's 2nd stage boolloader code
mov eax, 10000h
mov eax, [eax]
jmp eax
I'd be grateful if someone could tell me what instruction 2 does than instruction 1 doesn't.
Thx.
mov eax, 10000h ; eax = 10000h
mov eax, [eax] ; make eax = dword @ 10000h
jmp eax ; jmp to this value
could also be done like..
mov eax, 10000h
jmp dword ptr [eax]
Quite often that 10000h will be defined as a constant, so wherever it appears it will be the same, and it is a lot easier to change one definition than several.
Boot loaders usually relocate code so the address gets referenced at least twice - once to copy it to its address and then the jump, so using 'STAGE2ADDRESS equ 10000h' is often done.
Anyway, when you write your own boot code you get the basics going and rarely, if ever, go back and 'optimize' the ancient code (speaking from experience here... :bg)
Simplest code would be 'jmp dword ptr ds:[10000h]'
Re make eax = dword @ 10000h
So that's it!
I like your solutions much better.
The code was written by someone who was more or less a beginner himself @ the time.
I know this cos he includes a disclaimer saying as much.
Thx both
sinsi's form is the tidiest but a long instruction, not that it would matter in most instances. Just to make it more confusing, here is a small macro for the lazy.
;; ---------------
;; jump to address
;; ---------------
jta MACRO address
jmp dword ptr ds:[address]
ENDM
Which you would use like this.
jta 10000h
If you are a genuine purist you would use CS rather than DS but MASM converts DS to CS anyway as a PE file has data and code segments mapped to the same address range.
Interesting part is the DS prefix code is 1 byte shorter built by MASM.
00401045 FF2500000100 jmp dword ptr [10000h]
0040104B 2EFF2500000100 jmp dword ptr cs:[10000h]
hutch, since this is a boot loader's 2nd stage, I would assume that the cpu is in pmode from booting the 1st stage, a PE file is way off.
Sounds like 'OS construction' (which we know we can't do with the masm32 licence :bg)
>If you are a genuine purist you would use CS rather than DS but MASM converts DS to CS anyway
With flat it doesn't matter and the default memory access is through DS, so the CS override needs the prefix byte.
The 'ds:' is needed for masm for some obscure reason, even though it is 1)the default 2)no prefix byte needed.
Just for my edificiation; if this is bootloader coade (assuming pre-protected mode switch), then what are the rules for the size prefixes? Can you use the extended registers without a size operand in real mode? I'll see if I can't dig it out of an Intel manual when I get some time
-r
16-bit code that uses e.g. EAX always has the 66h (operand size) prefix. 67h is the address size prefix. 'unreal' mode code is usually full of 66s and 67s.
With 32-bit code, the 66h prefix is used for 16-bit regs e.g. AX - the exact opposite.
Yes you are right, at the boot loader stage you tend to roll your own.
Vaguely long long ago I remember that the so called UnReal mode switched to protected mode and back again to get 32 bit addressing, thank God I don't play with that stuff. :bg
All very helpful & thx for the macro
You're right we've just crossed into pmode for the above jmp.
Re cs this is the only reference I can find in stage 1 & 2 bootloaders
It happens in stage 1 (16 bit )
==============================================================.
mov ax, 0 ; set registers to code position
mov ds, ax
mov es, ax
push ax ; segment address onto stack
mov ax, 0h
push ax ; offset address onto stack
retf ; pop offset to ip, pop segment to cs <========================HERE
====================================================================
Again as a beginner it looks quite long winded
Whilst searching for 'cs' I came across cseg and noticed that the homemade gdt has 2 selectors cseg (code?) and dseg (data?)
I notice that
jmp cseg:goforth ; clear prefetch q upon jmp
is the last 16 bit instruction before Pmode and seems to jump to the very next instruction (on the disk image though prolly not in ram) which is the first of a sequence of instructions that
loads the dseg selector's addr into ds, ss, es, fs, gs (ie not cs)
followed by ...
sti
mov al, 0AEh ; enable keyboard
out 64h, al
mov eax, 10000h ;address with address to jump to
mov eax, [eax] ;make eax = dword @ 10000h <=======evincrn8's explanation above
jmp eax ;start Forth
I' a bit confused about the roles of cseg and dseg either side of PMode cos code and data look to be mixed together throughout.
A very simple explanation of what is going on above would be very helpful indeed.
BTW Re the 66h explanation. I was beginning to wonder about the accuracy of my disassembly. You've just restored my faith. Thx
I thought I'd got the answer but on reflection perhaps not!
Quote
I notice that
jmp cseg:goforth ; clear prefetch q upon jmp
is the last 16 bit instruction before Pmode and seems to jump to the very next instruction (on the disk image though prolly not in ram) which is the first of a sequence of instructions that
loads the dseg selector's addr into ds, ss, es, fs, gs (ie not cs)
The inter-segment jump is used to set CS and flush the instruction queue. Unlike the other segment registers, CS cannot be loaded with a MOV or POP instruction. CS is normally loaded with a far JMP, CALL, or RET instruction. The instruction queue must be flushed because it contains instructions that were decoded for execution in real mode.
That certainly wasn't apparent to me. Thank you for your concise explanation.
QuoteCS is normally loaded with a far JMP, CALL, or RET instruction.
i would add INT and IRET to Michael's list
quite often, they set an interrupt vector and use it to switch between modes
either of these instructions can alter the CS reg - very similar to FAR CALL / RETF
Thats great!
I read 'A crash course in protected mode' @ http://www.geocities.com/siliconvalley/2151/pmode.html.
before starting this thread.
It didn't treat cs any differently from the other reg's but seemingly it is.
The article focused more on gdts/selectors which I also need to know about.
Thx for enlightening me further
heh, if the code runs on an 8088/8086 then opcode 0Fh was legit (pop cs). Now, 0Fh is the first part of a sh*tload of 286+ stuff :bdg
Quoteif the code runs on an 8088/8086 then opcode 0Fh was legit
I have no way to verify if the instruction would execute (I think Dave does), but I can verify that MASM will not accept POP CS. Even with the default processor (.8086), MASM 5.1 returns:
error A2059: Illegal use of CS register
Try MASM 1.25 - that does it OK (I used that version for 10 years, even on my 486 - that's why I hate macros, since I had to write so many).
I'll try and dig it up and check.
My mistake, although I'm sure it is a legal opcode (the symmetry thing)
The Microsoft MACRO Assembler , Version 1.25
Copyright (C) Microsoft Corp 1981,82,83
0000 0F start: pop cs
E r r o r --- 59:CS register illegal usage
Warning Severe
Errors Errors
0 1
But see, it encodes it as 0F. Who has an 808x to test it on?
I think dedndave has a PC XT that still works.
you can't pop CS without a valid IP to go with it - lol
certainly, you can push CS
the 8088 has no tests for invalid opcodes - it generates no exceptions
it will execute whatever you put in front of it
that's why you can do things like AAM 9 to divide by 9
the opcode for AAM is D4 0A
with the 8086, you can put other values where the 0A is and it works - lol
but - don't expect MASM to do it for you - you have to hard-code it
db 0D4h,9 ;AAM 9
so - if you were to POP CS, there has to be valid code at the new CS:IP, or it will crash, of course
EDIT - i just fired up the old XT - lol
dang - the monitor is dead - no high voltage
it worked the last time i fired it up
the XT seems to boot, but the hard drive sounds like a bearing with no oil - lol
it is an old 40 MB seagate drive - it always was loud
Quote from: dedndave on October 24, 2009, 11:31:28 AM
you can't pop CS without a valid IP to go with it - lol
Sure you can. Not that that is a good thing.
Quote
certainly, you can push CS
the 8088 has no tests for invalid opcodes - it generates no exceptions
it will execute whatever you put in front of it
that's why you can do things like AAM 9 to divide by 9
the opcode for AAM is D4 0A
with the 8086, you can put other values where the 0A is and it works - lol
It works on other processors as well. But yes, you need to
hard code it. I've seen it in binary to hexadecimal conversion.
Back to POP CS, eek! It works on my 80186... DEBUG
doesn't decode it though. It shows as DB 0F.
Cheers,
Steve
Quote from: dedndave on October 24, 2009, 11:31:28 AM
EDIT - i just fired up the old XT - lol
dang - the monitor is dead - no high voltage
it worked the last time i fired it up
the XT seems to boot, but the hard drive sounds like a bearing with no oil - lol
it is an old 40 MB seagate drive - it always was loud
Hi,
Is that monitor MDA or CGA? If CGA you can use a TV set.
Ah yes, Seagate drives. I may have to see if I can get the
video back on my 8088. Opposite problem from you, good
monitor here.
Cheers,
Steve N.
hiya Steve - lol
yah - it has composite output, but i don't feel like messing with it at the moment - too many other things to deal with right now
i will fix the monitor later, hopefully - if not, i think i have another CGA monitor out in the shed
otherwise, i have a bunch of old "super vga" cards around that are XT compatible and several monitors i can use with them
HI Dave,
If you are capable of fixing high voltage circuits, I should probably
stop saying simpler things as advice. Somehow I ended up with a
CGA card, though I never had a system with one in it. I would go
with a SVGA myself rather than a CGA, but if you want one...
Oh the POP CS comment was in error. CS sure changed, but
due to an interrupt. Mea culpa, for not double checking until
after posting.
Oops,
Steve
:bg
I remember that CGA text mode on a good VGA screen used to look great and was instant fast. All of the decent development environments back then, MASM, MS-C and even quick basis ran in CGA text mode. You actually felt like you were typing into a computer, not one of the late GUI things. I have in an archive on te machine, my ancient development tools and they still run like rockets.
lol - np Steve
when i was a kid, my dad ran a tv repair business out of the basement
i was his "free employee" (i.e. slave) at a very young age
i learned electronics along the way - especially tv and radio circuits
i also put up hundreds of tv antennas and towers - in fact, i saved dad's ass from falling off a roof at about age 10
you don't know how many times i have pondered whether i should have let him, the antenna, and the rotor all drop - lol
but, yah - i can fix hv circuits - in fact, there aren't very many circuits i can't fix if i have the tools/equipment/parts/time
when i got out of the army, i went into computers and other digital circuits
after that, dad was the student