Page 1 of 1
Using ss0 in interrupt.
Posted: Mon Aug 03, 2015 7:45 am
by Jezze
Hi,
Most ISRs I've seen does this to set up their segment registers:
Code: Select all
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
I think hardcoding the value 0x10 is a bit ugly. Instead you could do this:
Code: Select all
mov %ss, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
This works because you've set ss0 in your tss.
This was just a minor tip. I think that should work. Anyone disagree?
Re: Using ss0 in interrupt.
Posted: Mon Aug 03, 2015 7:55 am
by Jezze
As I said this removes the need to hard code stuff. The other such pet peeve of mine is with the gdt:
This is from the wiki:
Code: Select all
reloadSegments:
; Reload CS register containing code selector:
JMP 0x08:reload_CS ; 0x08 points at the new code selector
.reload_CS:
; Reload data segment registers:
MOV AX, 0x10 ; 0x10 points at the new data selector
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
RET
As you can see here, the long jump has a hardcoded 0x08. Can we remove it? Yeah if we use long return instead. This below is AT&T syntax but does basically the same.
Code: Select all
.global cpu_setgdt
cpu_setgdt:
movl 4(%esp), %eax
lgdt (%eax)
movw 12(%esp), %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
pushl 8(%esp)
pushl (%esp)
lret
This would be the prototype for the above function:
Code: Select all
void cpu_setgdt(void *pointer, unsigned int code, unsigned int data);
Calling it with code = 0x08 and data = 0x10 would match the example from the wiki.
Do with it as you please. It's just a solution for those who don't like hard coded values.
Re: Using ss0 in interrupt.
Posted: Mon Aug 03, 2015 9:07 am
by Antti
Good tricks and definitely worth starting a discussion. However, I get an allergic reaction every time I see an unmatched call and ret. Of course, for the latter it is only a mild reaction because the cpu_setgdt routine is called. There still is a "near call/far return" mismatch that is a little bit itchy.
If I hold my breath, I can write few examples:
Code: Select all
ReadIp:
pop eax ; DO NOT USE
jmp eax ; DO NOT USE
RelocateBootSector:
push 0x0000 ; DO NOT USE
push NewLoc ; DO NOT USE
retl ; DO NOT USE
NewLoc:
There are two problems. First of all, it is very surprising for the CPU (an optimization issue). The other issue, that is usually far more important, is that it is a bad habit (beginners will embrace it and think it is a good trick).
Re: Using ss0 in interrupt.
Posted: Mon Aug 03, 2015 3:58 pm
by tkausl
Edit: Nevermind...
Re: Using ss0 in interrupt.
Posted: Tue Aug 04, 2015 5:00 am
by Antti
@Jezze: I did not mean to sound rude. I understand that all the optimization issues regarding to call & ret mismatchs are less than negligible and it is all about the taste of programming. What is not negligible is the avoidance of hard-coded values and you are very much on the right track when it comes to that.
Re: Using ss0 in interrupt.
Posted: Tue Aug 04, 2015 6:02 am
by bluemoon
But do we have different understanding on the definition of hard-code and constants?
This is hard-code, I agree it is bad too:
Code: Select all
MOV AX, 0x10 ; 0x10 points at the new data selector
MOV DS, AX
However, I totally accept constants:
Code: Select all
MOV AX, SEL_KDATA ; selector for kernel data
MOV DS, AX
And have the constant defined is an organised way and more meaningful naming convention.
And sure, you become more flexible get the value from ss, it's a trade off between dynamics and a nano-second.