2

I'm trying to follow the lab1 of MIT 6.828 to get some understanding about x86 bootstrapping.

The 1st instruction on boot up is: [f000:fff0] 0xffff0: ljmp $0x3630,$0xf000e05b

If I understand correctly, x86 compatible CPUs always start in real mode. I'm confused by the operands of this instruction. Is the first value $0x3630 used as cs register in the long jump and the next part $0xf000e05b used as the offset?

If this is the case then the target address should be 0x36300 + 0xf000e05b but the next instruction is [f000:e05b] 0xfe05b: cmpw $0xffc8,%cs:(%esi) which is at 0xfe05b. How is this address 0xfe05b calculated? Does the CPU make use of the upper 16-bits of the EIP register at all in real mode?

I tried to set the architecture to be i8086 and inspect the instructions and they still seemed to be interpreted as 32-bit instructions.

(gdb) set architecture i8086
The target architecture is assumed to be i8086
(gdb) x/5i 0xffff0
   0xffff0:     ljmp   $0x3630,$0xf000e05b
   0xffff7:     das
   0xffff8:     xor    (%ebx),%dh
   0xffffa:     das
   0xffffb:     cmp    %edi,(%ecx)
(gdb)
Joy
  • 321
  • 1
  • 9
Xianze
  • 21
  • 2
  • 2
    How are you disassembling the instructions. `ljmp $0x3630,$0xf000e05b` is a 32-bit instruction but the first boot instructions will likely be 16-bit code. TRy disassembling code at f000:fff0 as 16-bit and not 32-bit. When you decode as 16-bit code it will probably look like `ljmp $0xf000:$e05b` which starts executing code at an earlier part of the BIOS ROM. – Michael Petch Nov 27 '19 at 21:01
  • Come to think of it it looks like you might be in a debugger?? Tell us how you are viewing this code (and which program) and we can probably tell you how to switch to 16-bit disassembly. – Michael Petch Nov 27 '19 at 21:06
  • Yes I'm using gdb to debug qemu remotely through a port on localhost. I'm looking into how to switch to 16-bit disassembly. At the beginning of the debug session gdb already prints "The target architecture is assumed to be i8086". – Xianze Nov 27 '19 at 21:12
  • Use an option that shows raw machine code as well, so we can be more sure of what the disassembler is doing. Those instructions would require `66` operand-size and/or `67` address-size prefixes in 16-bit mode, if they're really being disassembled correctly (which I doubt). DAS is probably a byte that should have been another instruction. – Peter Cordes Nov 27 '19 at 22:46
  • 5
    There seems to be a gdb bug in recent versions that ignore the `set architecture i8086`. See [this answer](https://stackoverflow.com/a/55246894/547981) on the linked duplicate for a workaround. Also, consider using bochs with its built-in debugger which is better at handling real mode. – Jester Nov 27 '19 at 23:10

0 Answers0