Save/restore %ebp in __call16 instead of in caller (call16).

The Ubuntu gcc compiler apparently miscompiles code when %ebp is in an
    assembler clobber list.
Also, don't clobber %eax in transition32 - a minor cleanup.
diff --git a/src/romlayout.S b/src/romlayout.S
index 96aa836..319d7b4 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -174,9 +174,11 @@
  ****************************************************************/
 
 // Place CPU into 32bit mode from 16bit mode.
-// Clobbers: %eax, flags, stack registers, cr0, idt/gdt
+// Clobbers: flags, segment registers, cr0, idt/gdt
         DECLFUNC transition32
 transition32:
+        pushl %eax
+
         // Disable irqs
         cli
 
@@ -207,11 +209,12 @@
         movw %ax, %fs
         movw %ax, %gs
 
+        popl %eax
         retl
 
 // Call a 16bit function from 32bit mode.
 // %eax = address of struct bregs
-// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt
+// Clobbers: %e[bcd]x, %e[ds]i, flags, segment registers, idt/gdt
         DECLFUNC __call16_from32
         .global __call16big_from32
 __call16_from32:
@@ -278,10 +281,11 @@
 
 // Call a 16bit function from 16bit mode with a specified cpu register state
 // %eax = address of struct bregs
-// Clobbers: all gp registers, es
+// Clobbers: %e[bcd]x, %e[ds]i, flags
         DECLFUNC __call16
 __call16:
-        // Save eax
+        // Save %eax, %ebp
+        pushl %ebp
         pushl %eax
 
         // Setup for iretw call
@@ -323,8 +327,9 @@
         movl %ebx, BREGS_ebx(%eax)
         movl %edx, BREGS_edx(%eax)
 
-        // Remove %eax
+        // Remove %eax, restore %ebp
         popl %eax
+        popl %ebp
 
         cld
 
@@ -403,7 +408,7 @@
 
         .code16gcc
 
-        // IRQ trampolines
+// IRQ trampolines
         .macro IRQ_TRAMPOLINE num
         DECLFUNC irq_trampoline_0x\num
         irq_trampoline_0x\num :
diff --git a/src/util.c b/src/util.c
index 2c925fe..7358040 100644
--- a/src/util.c
+++ b/src/util.c
@@ -22,7 +22,7 @@
 #endif
         : "+a" (callregs), "+m" (*callregs)
         :
-        : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
+        : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
 }
 
 inline void
@@ -36,7 +36,7 @@
         "calll __call16big_from32\n"
         : "+a" (callregs), "+m" (*callregs)
         :
-        : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
+        : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
 }
 
 inline void