Reduce stack usage in call16().

Tell gcc that registers are clobbered instead of using push/popal.
diff --git a/TODO b/TODO
index 08aaf91..fa01392 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,7 @@
 Find out why ubuntu compiles are failing.  Find work around.
 
-See if it is better to tell gcc that call16 clobbers all registers
-instead of having the code call pushal/popal.
-
-The __call16 code does a long jump to the interrupt handlers - this is
-unnecessary.
+The __call16 code does a long jump to the interrupt trampolines - this
+is unnecessary.
 
 Fix makefiles so that they rebuild the required files automatically.
 
diff --git a/src/util.h b/src/util.h
index 7de577b..6c707bd 100644
--- a/src/util.h
+++ b/src/util.h
@@ -65,16 +65,18 @@
 void call16(struct bregs *callregs)
 {
     asm volatile(
-        "pushfl\n"   // Save flags
-        "pushal\n"   // Save registers
+        "pushl %%ebp\n" // Save state
+        "pushfl\n"
 #ifdef MODE16
         "calll __call16\n"
 #else
         "calll __call16_from32\n"
 #endif
-        "popal\n"
-        "popfl\n"
-        : : "a" (callregs), "m" (*callregs));
+        "popfl\n"       // Restore state
+        "popl %%ebp\n"
+        : "=a" (callregs), "=m" (*callregs)
+        : "a" (callregs), "m" (*callregs)
+        : "ebx", "ecx", "edx", "esi", "edi");
 }
 
 static inline