13

In x86 assembly language there are two registers named BX and DX. In the 32bit architecture, their names are EBX, EDX and in 64bit RBX and RDX. The lower byte is respectively BL, DL and the higher byte BH and DH.

Writing in assembly language, it is most common practice, lower case to be used: bx,dx, ebx, edx and so on.

As you can see, in lower case these register names are much less readable, because the letters "b" and "d" look very similar.

One possible explanation of this phenomenon was provided by this answer. In assembly language, in contrast to high level languages and regular text, the source is organized by columns.

The reading of this source is not clear left-to-right, but column wise. This way, the horizontal differences between "b" and "d" are not enough for clear distinction between them. See the example source in NOTE3.

I have an idea, that for the assembly language source editor, some font has to be developed, where these 2 letters to be clearly different.

But how this goal can be achieved without sacrificing legibility of the text? In other words - how to make these letters to be completely different and in the same time to remain "b" and "d" usual letters?

NOTE1: I am not looking for suitable "programming font". I have nothing against to draw it myself. The big question is what actually to draw. :)

NOTE2: removed

NOTE3: One example of problematic source code (function edx=abs(edx), ebx is used as a scratch register):

mov  ebx, edx
sar  ebx, 31
xor  edx, ebx
sub  edx, ebx

The same code with a bug:

mov  ebx, edx
sar  ebx, 31
xor  ebx, edx
sub  edx, ebx

The same code using ecx as a scratch register - it looks much more clear:

mov  ecx, edx
sar  ecx, 31
xor  edx, ecx
sub  edx, ecx

... and with the same bug:

mov  ecx, edx
sar  ecx, 31
xor  ecx, edx
sub  edx, ecx
13
  • 15
    I'm not sure everyone would agree that b and d are all that similar.
    – DA01
    Aug 8, 2013 at 20:19
  • 2
    What about trying to make the d more like a greek delta, δ?
    – Pål GD
    Aug 8, 2013 at 22:26
  • 6
    I fail to see b and d as similar looking.
    – Mohit
    Aug 9, 2013 at 5:30
  • 3
    Dyslexic people have significantly more problems with this distinction. p and q have the same issue. (But IIRC not p and d - it's a left-right, not up-down issue). "Works for me" is not an answer here.
    – MSalters
    Aug 9, 2013 at 8:24
  • 3
    @Mohit Although I fail to see b and d as similar looking, I cannot at a glance (or two, or three) see the difference between the correct section of assembly code and the buggy section of assembly code. Indeed, there is a masking effect going on, whereby the surrounding material conceals the difference between b and d.
    – Kaz
    Aug 10, 2013 at 2:12

11 Answers 11

19

The principal problem to my eyes is that I'm scanning column wise instead of left to right. Any marks that appear towards the bottom of the character indicating 'b' or 'd' would not be enough for my eyes to quickly determine the character.

I suggest you make a change to one of the character's top strokes. Maybe a one pixel dot towards the 'inside' (left if 'd', right if 'b') at the top.

If you make the dot on the outside then you'd have to scrunch everything else in. That'd be even more of a visual clue but it would also be jarring when reading right to left.

A quick edit on Deja Vu Sans Mono shows what I mean. Its basically adding a serif to a sans font. Changed Deja Vu Sans Mono to a new b

If you're willing to accept a little clutter I added a dot in the middle as someone proposed.

enter image description here

4
  • 2
    +1 for one-pixel dot. It works well with 0 and O for me, so I imagine it is even better to differentiate the less similar characters b and d. Aug 9, 2013 at 2:13
  • 3
    Very smart observation is that in assembly language, the text is not scanned left-to-right, but column wise. This way, left-right asymmetry of "bd" is not enough. In normal text, this effect does not exists.
    – johnfound
    Aug 9, 2013 at 4:54
  • I accepted your answer, but because the solution is better than others but because of the great analyze of the problem.
    – johnfound
    Aug 10, 2013 at 17:12
  • The serif looks really weird to me, I would probably think it's a different character than 'b' if I saw it for the first time. And it doesn't even help that much. On the other hand, the dot idea is genius and I can clearly recognize the difference. Aug 14, 2013 at 11:14
16

You may be able to play around with the idea of drawing them both using a single stroke, and differentiating by a small gap in between the vertical and the c curve. For "b" you could leave a gap at the top point where the c meets the l, and for "d", the gap could be left at the bottom instead.

This effectively makes it appear as 1 stroke, or 2, and might actually make the letters much more visible?

EDIT: real quick image to explain, would have to be messed with for legibility, but might work?

maybe something like this

2
14

As I mentioned in a comment, I don't think 'b' and 'd' are necessarily two characters that are confusing to most people. So there may be of limited interest/use in such a typeface.

one and I and lowercase-L are confusing because they are often the exact same glyph in a lot of typefaces. Zero and O, thought usually slightly different are often seen as the same glyph as well, hence the slash-zero.

That said, dyslexia is one condition where having more distinct differences between b and d may be quite useful. If you do a search on 'typefaces for dyslexia' you will find plenty of examples. Here's one:

Special b and d in Heinemann Special

Source: http://weandthecolor.com/heinemann-special-fonts-colection/29643

2
  • In this answer very smart observation explains why "b" and "d" are not readable enough in assembly source code, but they are OK for normal text or HLL soures.
    – johnfound
    Aug 9, 2013 at 5:14
  • 1
    @johnfound I don't write assembly, so perhaps that is a very niche situation where people get confused by the two letters. That said, if the issue is that it's read in columns, and you only focus on the top part of the letter, I have to wonder why it's not written in uppercase. Sounds like a poorly conceived language syntax.
    – DA01
    Aug 9, 2013 at 14:40
11

I think you've asked a leading question and are therefore getting answers that match your initial guess at the solution.

The font variation answers are interesting for solving the general problem of distinguishing similar characters, and are particularly helpful for dyslexic readers, but in your case, you actually need to distinguish words, not characters.

You should be able to set up syntax highlighting in your editor to give the different register names different colours, a crude example:

enter image description here

There are enough x86 registers that picking distinct colours for each is likely to be difficult, so a more subtle approach could be to share colours between registers that have common conventional usages (inputs, outputs, temporary, indexes, etc.)

4
  • Usually, the syntax highlighter, uses the same color for the same syntax context. I am afraid coloring of the same syntax elements (register) with different color might be confusing.
    – johnfound
    Aug 12, 2013 at 6:32
  • I know that's the usual case, but that can be fixed relatively easily. Most editors have the ability to customise the list of keywords for different languages. I made the screenshot above in emacs in about 5 seconds using the highlight-symbol package. It isn't persistent or automatic, but that could be fixed with some more effort.
    – Tom
    Aug 13, 2013 at 10:11
  • 2
    I agree it could be confusing if done badly, but so is using the same colour for all registers.
    – Tom
    Aug 13, 2013 at 10:13
  • 2
    I think this is the best solution since you quickly see where's what
    – Michael
    Aug 30, 2013 at 9:32
3

Interesting idea and level of detail in the thinking.

My thought would be that the differentiating element between the two is the direction of the c-curve. So emphasize on that - may be make it thicker.

Also, the eyes follow lines and strokes, if you give the c-curve a stroke where it thickens in the middle it'll help the eye focus on it more and follow the direction of the curve.

Here is an example of two differences applied to the c-curve:

a) Shape b) Storke

enter image description here

3
  • Please provide some example or more detailed description. IMHO, the direction of the letter is not very important. For example all latin languages accept the letter "Я" as a "R" - some kind of weird written, but "R".
    – johnfound
    Aug 8, 2013 at 19:59
  • Added a couple of examples of the difference the c-curve can make
    – Alok Jain
    Aug 9, 2013 at 0:11
  • I don't think this will work well on smaller texts.
    – Lie Ryan
    Aug 9, 2013 at 4:38
2

Use a thick font and implement color/shade mnemonics. If you do it consistently for all connected registry names, it would have a stronger impact on legibility and quick visual recall than the typeface tweaks.

2

I suspect that adjusting the font is not the best way to help people differentiate between 'b' and 'd' or any other characters where the problem is not normally noticed (i.e. that are reasonably different already, unlike, for example, "1","l", "I", and "|").

Instead, you could:

  • automatically switch all instances of 'b' and 'd' to upper case (or just switch one of them)
  • use different text colours for 'b' and 'd' (your editor might be able to handle this just through highlighting)
  • use different background colours for 'b' and 'd'
  • use italic, bold, or underlined text for one of the two

Here are all of the possibilities those manipulations afford, with no need to touch the font:

easier manipulations that changing font

...and here is what you could have with possibly the easiest solution, which is using context-highlighting (of text colour) by word (side note: colours b lue and re d):

context-highlighting by word

By the way, in creating this I noticed that the font Consolas (very widespread and likely to be pre-installed on many machines) has 'b's and 'd's similar to the special font mentioned by DA01.

1

The fix is to get rid of Intel assembly language syntax, and replace the registers with R0, R1, R2 like sanely designed assembly languages.

Think about it: the architecture renowned for a small number of registers uses the longest names for them in the assembly notation.

The plain names Rn could refer to the natural size, 32 or 64 bits. Suffixes can be used for the partial register stuff. For instance r1.hb (high byte (of lower 16 bit word) of r1) corresponds to bh.

This has already happened to some extent. The x86-64 extension to the architecture uses the names R8, R9, ... for additional registers beyond the core ones carried over from x86, which are called RAX, RBX, ..., RSI, RDI, RBP, RSP.

It's not a big step to allow R1 as an alternative spelling for RAX, and you can already do this for yourself in any halfway decent macro assembler (or even a non-macro assembler that is preprocessed with the C preprocessor).

Macros for register names are not unheard of. They are used on MIPS for instance, where registers have special names, as well as global numbers. For instance $gp $sp and $fp are also $28, $29 and $30.

Proof of concept to dispel claims that this is as infeasible as changing the ASCII code.

Starting with this small C translation unit:

void vec_add(int *out, int *a, int *b, int n)
{
  int i;

 for (i = 0; i < n; i++)
    out[i] = a[i] + b[i];
}

We can use GCC to obtain this assembly:

    .globl  vec_add
vec_add:
.LFB0:
    pushl   %edi
    pushl   %esi
    pushl   %ebx
    movl    16(%esp), %ebx
    movl    20(%esp), %esi
    movl    24(%esp), %edi
    movl    28(%esp), %ecx
    testl   %ecx, %ecx
    jle .L1
    movl    $0, %eax
.L3:
    movl    (%esi,%eax,4), %edx
    addl    (%edi,%eax,4), %edx
    movl    %edx, (%ebx,%eax,4)
    addl    $1, %eax
    cmpl    %ecx, %eax
    jne .L3
.L1:
    popl    %ebx
    popl    %esi
    popl    %edi
    ret

Replacing the register names with a search and replace script and adding a header #include:

#include "reg.h"

    .globl  vec_add
vec_add:
.LFB0:
    pushl   r5
    pushl   r4
    pushl   r1
    movl    16(r6), r1
    movl    20(r6), r4
    movl    24(r6), r5
    movl    28(r6), r2
    testl   r2, r2
    jle .L1
    movl    $0, r0
.L3:
    movl    (r4,r0,4), r3
    addl    (r5,r0,4), r3
    movl    r3, (r1,r0,4)
    addl    $1, r0
    cmpl    r2, r0
    jne .L3
.L1:
    popl    r1
    popl    r4
    popl    r5
    ret

This is saved in a file having a .S suffix. The capital S tells GCC that this is assembly language which requires the C preprocessor.

Note how much more readable this is. Except, that is, for the minor point that the stack is being referenced somewhat cryptically as r6, which could be fixed by having an alias sp for esp.

The file with our custom register names assembles cleanly and makes an object file which we can disassemble:

$ gcc vec.S -c
$ objdump -S vec.o

vec.o:     file format elf32-i386


Disassembly of section .text:

00000000 <vec_add>:
   0:   57                      push   %edi
   1:   56                      push   %esi
   2:   53                      push   %ebx
   3:   8b 5c 24 10             mov    0x10(%esp),%ebx
   7:   8b 74 24 14             mov    0x14(%esp),%esi
   b:   8b 7c 24 18             mov    0x18(%esp),%edi
   f:   8b 4c 24 1c             mov    0x1c(%esp),%ecx
  13:   85 c9                   test   %ecx,%ecx
  15:   7e 15                   jle    2c <vec_add+0x2c>
  17:   b8 00 00 00 00          mov    $0x0,%eax
  1c:   8b 14 86                mov    (%esi,%eax,4),%edx
  1f:   03 14 87                add    (%edi,%eax,4),%edx
  22:   89 14 83                mov    %edx,(%ebx,%eax,4)
  25:   83 c0 01                add    $0x1,%eax
  28:   39 c8                   cmp    %ecx,%eax
  2a:   75 f0                   jne    1c <vec_add+0x1c>
  2c:   5b                      pop    %ebx
  2d:   5e                      pop    %esi
  2e:   5f                      pop    %edi
  2f:   c3                      ret    

The reg.h include file, of course, just contains this:

#define r0 %eax
#define r1 %ebx
#define r2 %ecx
#define r3 %edx
#define r4 %esi
#define r5 %edi
#define r6 %esp
#define r7 %ebp
10
  • This would be most confusing with instructions that implicitly access a known register (e.g. ecx used as a counter with the rep prefix).
    – ugoren
    Aug 9, 2013 at 5:23
  • 1
    @ugoren So you're saying that if rcx is called r2, it's suddenly confusing to have an instruction that implicitly uses it? In that case, make the syntax explicitly use the register (but be restricted to that register). Yes, assembly languages have stuff like this! MIPS's stack pointer ($sp) is also just register $29. Stuff happens to register 29 in instructions that do not mention it or $sp.
    – Kaz
    Aug 9, 2013 at 5:41
  • Yes - everybody knows that rcx is implicitly used as a counter, nobody knows r2. Other instructions use other registers, including rbx and rdx. Making it implicit is much more complicated than changing the font - it requires knowing all instructions. In MIPS, you never see $29 - only $sp - so you want names, not numbers.
    – ugoren
    Aug 9, 2013 at 6:35
  • 2
    -1. This is about as realistic as proposing to change ASCII.
    – MSalters
    Aug 9, 2013 at 8:32
  • 1
    @MSalters it is completely realistic, and I could do it today, if I wanted to program in x86 assembly.
    – Kaz
    Aug 9, 2013 at 15:11
0

Source Code Pro?

It was specifically designed to better-distinguish between commonly-mistakable characters in programming editors.

enter image description here


b and d are tough, though. Consider this font list, too.

1
  • 7
    It is not enough. Usual "programming fonts" concentrate on "i","l","1","0","O" characters. The "b" and "d" characters are easy distinguishable in the normal high level languages (like C/C++/Pascal, etc) because they are used in long words. In x86 assembly the register names are very short and with only one char difference - ebx vs edx for example.
    – johnfound
    Aug 8, 2013 at 19:32
0

If you look at most fonts they are distinguished by the side of the curve and the shape of the curve. I would take it one step further and change the height of the curve. If you notice right now most curves on db start at nearly the same midpoint of the vertical line. Perhaps move one down and one up. Also exaggerate the already present curve differences (b curve intersects at end of line, d takes it up a little bit leaving a tail).

0

OpenDyslexic is a free font especially designed for dyslexic users (and now used by Wikipedia, too):

Letters have heavy weighted bottoms to indicate direction. You are able to quickly figure out which part of the letter is down which aids in recognizing the correct letter, and sometimes helps to keep your brain from rotating them around. Consistently weighted bottoms can also help reinforce the line of text. The unique shapes of each letter can help prevent confusion through flipping and swapping.

A comparison of critical letters in some fonts:

comparison of fonts "Gill Sans", "Verdana", "OpenDyslexic", "Times" and "Helvetica"
OpenDyslexic uses unique letter shapes, to help prevent confusion.

The d seems to have this little stroke down, while it’s omitted for the b. And the right side of d resp. the left side of b is heavier.

letters in comparison: b, p and d (with heavier top and heavier bottom)
A heavier bottom is used to show which way is supposed to be down.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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