So I have an embedded machine from the late 80s I want to mess around with. It uses a NEC v20HL which is an 8088 compatible with some extra 80186 instructions tossed in. I know it uses 64k code segments, reset vector at 0xFFFF0 and ISRs at 0x00 on even addresses.

I have tried a bunch of different architectures and the only one that looks like 8088/x86 old school is the x86 real 16bit.

I don't understand how to actually use that information as IDA disassembled even the reset jmpl wrong (EA 0000 FDAF) is clearly a far jump to seg 0 add 0xFDAF but IDA makes it seg000:0xDAF0. What is even worse is 0xFDAF jumps to a faulty instruction?..

  • Do you have IDA pro? – Ricardo Jul 6 '19 at 18:35
  • @Ricardo No, 7 Free – uMinded Jul 6 '19 at 19:45
  • how did you load your binary? – Igor Skochinsky Jul 6 '19 at 19:50
  • I don't see any 8088 or 80186 in the supported processor list of IDA. hex-rays.com/products/ida/processors.shtml – Ricardo Jul 6 '19 at 22:26
  • @IgorSkochinsky The file is a binary dump from an EPROM. I load it like any other and select x86 16bit. From there I am not sure how to create the proper sections so that far jumps actually map properly. – uMinded Jul 8 '19 at 4:03

So, it's a little difficult to describe it without the actual file but I'll try. For proper disassembly, you should load code so that it matches the expected addresses. For example, last 64K should normally be loaded into segment F000, so that the first byte of that segment is at F000:0000, or linear address 0xF0000 (seg<<4 + ofs).

Some simple rules of thumb:

  1. 64KB binary: load at F000:0000 (0xF0000)
  2. 128KB binary: load at E000:0000 (0xE0000)
  3. 256KB binary: load at C000:0000 (0xC0000)
  4. 512KB binary: load at 8000:0000 (0x80000)

Next, you'll need to create segments based on far jumps and calls, for example:

EA 00 00 FD AF jmp far ptr 0AFFDh:0

means there is a segment with the base 0xAFFD, so, create the following segment:

 start address: 0xAFFD0 (base<<4)
 end address: 0xBFFD0 (maximum 64KB long)
 base: 0xAFFD
 (*) 16-bit

next, go through disassembly and look for other far jumps/calls to gather other possible segment bases (a good source for that is the problems list). Create corresponding segments (you will likely have to truncate some of the previously created ones; this is normal as segments using full 64KB are not very common). You may also need to use a start address not at seg:0 but small offset, e.g. seg:7 (so seg<<4 + 7).

For most BIOS ROMs it may be be useful to create at least the last two segments (E000 and F000) straight away.

For more info on how segmentation works in IDA, see here.

Related question: Segments in IDA. How to overcome NONAME problem

| improve this answer | |
  • From that related question this cleared things up for me: "What seemed to be happening was that the linker was placing every object file into its own segment, so every inter-object function invocation was rendered in the binary as a far call, where the segment base was the base given to all functions within the module. I.e., the case you mention in your reply to Igor's comment did not materialize for me." Essentially the asm/ld is just being efficent, unless the coder is trying to obfuscate manually it should have no overloaps. – uMinded Jul 10 '19 at 14:53
  • As an aside, this may actually be useful as each code segment, if linked in the above way would make obviously related code chunks quite visible. Combine this with the fact I see strange chunks of 0x00 padding in the rom this may be the case. – uMinded Jul 10 '19 at 14:56
  • Would a good tactic be to make a segment 64k, find the first far jump and shrink the segment you are leaving to end at that jump. Then keep wandering the code making segments and shrinking as I go. Once I run out of far jumps I can expand the tail end of segments to the start of the next? It would be easier if you could just have a bazillion overlapping segments by paragraph and then have IDA mark the only ones used... – uMinded Jul 10 '19 at 14:59
  • I'd probably make a script to scan the database for all EA/9A opcodes, gather and sort all segment and offset values, then make a sort of a map to create non-overlapping segments. – Igor Skochinsky Jul 11 '19 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.