Aside from the = vs == bug which probably wasn't too damaging, the problem was caused because the newer compiler doesn't use as many registers in its code, specifically the EBX register. So at the start of the do_vgabios() function it doesn't bother to push EBX on the stack to preserve it. However code higher up that calls this function had stored something in EBX, which the call to the vgabios happily trashes.
The fix is to push ebx within the real_mode_switch_call_vga function: /* save the stack */ "push %ebx\n" "mov %esp, __stack\n"
...
" mov %ax, %ss \n" " mov __stack, %esp\n" "pop %ebx\n" );
It won't hurt to push other registers like %esi for example. In fact why not push all the registers just to be safe...
This is a pretty subtle bug, people should understand what was wrong and how the fix works.
-Dave
Dave Ashley linuxbios@xdr.com writes:
Aside from the = vs == bug which probably wasn't too damaging, the problem was caused because the newer compiler doesn't use as many registers in its code, specifically the EBX register. So at the start of the do_vgabios() function it doesn't bother to push EBX on the stack to preserve it. However code higher up that calls this function had stored something in EBX, which the call to the vgabios happily trashes.
The fix is to push ebx within the real_mode_switch_call_vga function: /* save the stack */ "push %ebx\n" "mov %esp, __stack\n"
...
" mov %ax, %ss \n" " mov __stack, %esp\n"
"pop %ebx\n" );
It won't hurt to push other registers like %esi for example. In fact why not push all the registers just to be safe...
This is a pretty subtle bug, people should understand what was wrong and how the fix works.
Well it is a little less subtle than it might be. In the C calling conventions frequently some of the registers are designated callee save. Which means if you are going to use that register you must save it. %ebx, %ebp, %esi, and %esi are the callee save registers on x86.
With inline assembly you can avoid some of that by telling the compiler which registers you will be using and it will handle the nuances of the calling conventions. That is possibly the better approach.
Eric
This bug has been already fixed in the CVS (v1) as of 2003/09/24. (I remember you said you were using old source)
On Thu, Nov 20, 2003 at 03:08:00PM -0800, Dave Ashley wrote:
Aside from the = vs == bug which probably wasn't too damaging, the problem was caused because the newer compiler doesn't use as many registers in its code, specifically the EBX register. So at the start of the do_vgabios() function it doesn't bother to push EBX on the stack to preserve it. However code higher up that calls this function had stored something in EBX, which the call to the vgabios happily trashes.
The fix is to push ebx within the real_mode_switch_call_vga function: /* save the stack */ "push %ebx\n" "mov %esp, __stack\n"
...
" mov %ax, %ss \n" " mov __stack, %esp\n"
"pop %ebx\n" );
It won't hurt to push other registers like %esi for example. In fact why not push all the registers just to be safe...
This is a pretty subtle bug, people should understand what was wrong and how the fix works.
-Dave _______________________________________________ Linuxbios mailing list Linuxbios@clustermatic.org http://www.clustermatic.org/mailman/listinfo/linuxbios