I'm trying to analyze a MS-DOS COM file that I wrote a few years ago with IDA Free 5.0, I've since renamed the segment to code_and_data and named constants and set data types correctly. However, when looking at the disassembly, I get db pseudo-instructions in the listing, like this:

code_and_data:0106 replacement_irq_handler:                ; DATA XREF: start+81o
code_and_data:0106                 cli
code_and_data:0107                 push    bx
code_and_data:0108                 db      3Eh
code_and_data:0108                 cmp     byte ptr ds:3BEh, 'C'
code_and_data:010E                 jnz     short call_original_dos_interrupt_handler
code_and_data:0110                 db      3Eh
code_and_data:0110                 cmp     byte ptr ds:3C0h, 'A'
code_and_data:0116                 jnz     short call_original_dos_interrupt_handler
code_and_data:0118                 db      3Eh
code_and_data:0118                 cmp     byte ptr ds:3C2h, 'K'
code_and_data:011E                 jnz     short call_original_dos_interrupt_handler
code_and_data:0120                 db      3Eh
code_and_data:0120                 cmp     byte ptr ds:3C4h, 'O'
code_and_data:0126                 jnz     short call_original_dos_interrupt_handler
code_and_data:0128                 db      3Eh
code_and_data:0128                 cmp     byte ptr ds:3C6h, 'N'
code_and_data:012E                 jnz     short call_original_dos_interrupt_handler
code_and_data:0130                 push    StartOfIndexTable
code_and_data:0133                 pop     bx

I understand that there are no additional bytes there, since the db and the cmp instruction after it start at the same address (see left column). Why does IDA show/add those db pseudo-instructions?

Is there any way to tell it to not show those, or is there a reason why it might be useful (I could only guess that since the same segment is both used for code and data, it tries to be "helpful" and show the code as data as well)?

But if so, why does it only show the first byte of the instruction (if you look at the addresses on the left again, these instructions are longer than 1 byte).

  • 1
    Isn't a db statement a decompiler's way to say "I can't make sense of it, can you?" – rackandboneman Aug 25 '17 at 20:45

The byte 3Eh is the encoding of the segment override DS:. You observe it in an instruction like

cmp     byte ptr ds:3BEh, 'C'

The hex encoding of this instruction is (I did this manually, some bit might be wrong)

3E    - segement override prefix
80    - 8 bit ALU instruction
3E    - mod/rm byte (reg = 7 -> instruction is CMP, mod = 0/rm = 6 -> immediate address)
BE 03 - offset of data to compare
43    - immediate data byte

The sequence 3E 80 3E BE 03 53 is 6 bytes long, which matches the actual instruction length of 6 bytes (010Eh - 0108h). If you assemble the assembler source code as given by IDA using a standard x86 assembler (like MASM), the DS: prefix will be ommitted, because the addressing mode "immediate address" is relative to the data segment by default. IDA shows the extra DB instruction to tell you (or an assembler that tries to re-assemble the listing) that the redundant, superflous segment prefix is actually encoded in the binary. If you want to hide that information, check Options -> General -> Analysis -> "Processor specific analysis options" -> "Don't display redundant instruction prefixes".

  • Thanks, that is really detailed. The instruction's hex encoding you specified is the same as in my input file. And the option was what I was looking for, enabling it does hide the db pseudo-instructions in the listing. Cool! – Thomas Perl Aug 25 '17 at 18:35

Edit: Thanks Michael for the clarification, these are not Branch hints, but Segment Prefixes. Keeping the answer for a reference and for people coming from search engines.

These are "Branch Hints" which aim to give the processor a "hint" as to whether or not a branch is likely to occur.

Branch Prediction

It used for optimization that is called Branch Prediction — an attempt that is done by the processor to predict which branch the code would take. The CPU is able to keep processing by making an assumptions about the direction of a branch before a condition is resolved. Otherwise, it was "sitting" and waiting for the condition the branch is dependent on to be resolved.

From Wikipedia:

In computer architecture, a branch predictor is a digital circuit that tries to guess which way a branch (e.g. an if-then-else structure) will go before this is known for sure. The purpose of the branch predictor is to improve the flow in the instruction pipeline. Branch predictors play a critical role in achieving high effective performance in many modern pipelined microprocessor architectures such as x86.

Branch Hints

You can hint the CPU about the likelihood that a branch would be taken by using hint bytes that are inserted before a conditional jump instruction. This is done by using branch-hint-bytes which are inserted immediately before the conditional jump instruction.

The bytes are 3Eh and 2Eh and respectively they mean as follows:

2Eh - hint that the branch will not occur most of the time.
3Eh - hint that the branch will occur most of the time.

More Information:

You can read more about branch hints and optimisation here (recommended) and here.
If you want to read more about Branch Prediction I recommend this article about Dynamic Branch Prediction.

  • Makes sense, thank you -- I know the concept of avoiding branch mispredictions from GLib's G_LIKELY() / G_UNLIKELY() macros, interesting to see that branch hints have been around for so long. So is that a shortcoming of IDA to not generate pseudo-assembly for those? – Thomas Perl Aug 25 '17 at 13:53
  • 2
    downvoted because this answer is misses the question. 2Eh and 3Eh only work as branch hints if they prefix a jump instruction. In this case, they prefix a memory instruction and work in the original way - that is as segment prefixes. – Michael Karcher Aug 25 '17 at 18:16

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.