# Is BX the Base Address Register, and if so why?

I've seen a lot of posts on BX. I believe today, it's a "General Purpose Register". I'm confused at why people call it the Base Address Register,

• Why it's called the Base Address register, historically.
• Is any of that still relevant today?
• Is there a convention to reserve it's use for base-addressing?

You can see it being called that here.

• Thinking of it, this isn't exactly a RC question, as it doesn't target anything about old computer - especially not since it asks for relevance today. This question would be better suited on SE main site - and a quick search shows that variations have been asked there a lot. – Raffzahn Sep 19 '18 at 10:52
• I think a key here is that registers on x86 are only "more or less general purpose", you can use any of them in the basic operations but there are/were situations where you were restricted as to which registers you could use. – Peter Green Sep 19 '18 at 13:30
• Another key point is that comparing historical usage and modern day usage is misleading when it comes to x86 (I’m assuming here that the comment about “General Purpose Register” really refers to EBX/RBX rather than BX). Current x86 is backwards-compatible with the 8086, but modern-day x86 assembly-language programming is very, very different compared to 8086 programming (or even 386 programming); so the usage of BX doesn’t necessarily say much about the usage of EBX/RBX. – Stephen Kitt Sep 19 '18 at 16:13

BX has always been one of the general registers, and it has always been called the base register (see for example The 8086 Primer, page 19). It is the base register because it can be used in various based addressing modes: storing an address in BX, and an offset in SI or DI (the source and destination index registers respectively), allows memory to be accessed at BX + SI or BX + DI (ibid, page 31), or BX + SI + immediate, or even BX + immediate. It also serves as the base for XLAT.

BP is similar, and supports all the above addressing modes. The difference between BX and BP is that BX defaults to the data segment (DS), whereas BP defaults to the stack segment (SS). (BX and BP each have their own specific instructions too — e.g. XLAT uses BX, ENTER and LEAVE use BP.)

Those addressing modes still exist today, so their use is still relevant, but indexed and indirect addressing are available with any general, pointer or index register starting with 32-bit x86. While BX and BP are “special” on 16-bit x86, in that they are the only registers with which indirect or indexed addressing is possible, that is no longer the case on 32- or 64-bit x86 so EBX, EBP, RBX, and RBP aren’t quite so special. (BP, EBP, and RBP are still somewhat special since they select SS as the base register in 16- and 32-bit mode, and can’t be used as pointers without an offset, i.e. there is no opcode for MOV AX, [BP] and MOV AX, [BP+0] ends up being used instead.)

There is no convention I’m aware of to specifically reserve the use of BX for base-addressing; if you need to use it for base-addressing, you set it up appropriately and use it. If the calling convention in use mandates that BX is preserved, you need to ensure you take that into account (as caller or callee depending on the convention and the code you’re writing).

• +2 for addition of XLAT/ENTER/LEAVE. – Raffzahn Sep 19 '18 at 15:59

Why it's called the Base Address register, historically.

Well, it isn't. If it all, then it would be 'Base Index' (or better Index Base), as it was in original 16 bit addressing the only register that could be added as a 'Base' in all indexed addressing. Indexed with SI or DI that is. (*1)

This addressing was symmetric with BP as Base Pointer. The basic idea was that an array can be pointed at with BX and addressed via SI or DI without further ado - or BP when within the stack (*2)

Beside that it's one of the original general purpose two byte registers.

Is any of that still relevant today?

Not really. At least not in 32/64 bit mode. REX addressing allows the use of any of the 'classic' register as (index) base in 32 Bit mode - except BP/SP (*3). In 64 bit mode 12 of the 16 registers can be used the same way (Not BP/SP/R12/R13 (*4)).

Now, having said that, 'Long' mode with 16 bit protected mode code segments comes along. Here classic (16 Bit) encoding is used together with 32/64 bit register size. BX retains its encoding advantage, as SIB is not needed. How much this rather forgotten mode is relevant is up for discussion.

Is there a convention to reserve its use for base-addressing?

Not really. Use as needed. After all, this is Assembly - there is no convention you don't want :))

The only issue to keep in mind is preserving it for your caller (unless it's explicitly not done)

You can see it being called that here.

Err ... lets say he's not wrong, but I would recommend looking for better in-detail description to learn about x86 (Check Wiki(books) or OSDEV-Wiki). Or if it is specific about classic (16 Bit) x86 programming, then there is only one book you to read: Steve Morse' 8086 Primer. 32/64 Bit is different anyway and need to be learned without these classic assumptions to be really useful instead of a rucksack of special cases on special cases.

*1 - If you want to assign mnemonic names to the 4 basic two byte registers, it might be

• AX = Accumulator. Used for Arithmetic (or Always the shortest encoding)
• BX = Base. Used as a pointer to data (structures)
• CX = Counter. Used in shift/rotate, string ops and loops.
• DX = Data. Used in arithmetic and I/O.

*2 - Then again, in case of 'standard' programming BP does hold the stack frame, so an index here is always an index into that frame, unless BP is temporarily moved.

*3 - SP can also be used with SIBencoding.

*4 - SP/R12 again with SIB encoding.

• REX addressing allows [using any register in 32-bit mode] -- did you mean SIB here? – ilkkachu Sep 19 '18 at 14:20
• @ilkkachu Nop. At least not as far as I remember. REX allows to use r/m mode with all registers. SIB is only needed for SP and R12. And of course if you want to use scaling ... or did I screw that up? I have to check again. – Raffzahn Sep 19 '18 at 15:05
• Mm. I know it's possible to use all of the registers as pointers in 32-bit mode, so it can't be REX. Actually, it seems that in 32-bit mode, just the modr/m byte is enough to use a single register as an address, no SIB needed for that case (except for ESP). wiki.osdev.org/… – ilkkachu Sep 19 '18 at 15:14
• @ilkkachu Jup, but you're right as well, to use a register as base with another one as index, SIB is needed. Let me doublecheck this and correct my answer. ok? – Raffzahn Sep 19 '18 at 23:48

BX is the oldest indexing register. Typically an element in a struct would be accessed by [BX + constant]; hence its name (or possibly the name comes from [BX + SI]; only BX or BP could be used on the left side, and only SI and DI could be used on the right side).

I couldn't find a particular thing about ebx/rbx except for it's the lowest register not clobbered by a specific instruction (mul/div/shl/shr) so it's a good place to put a pointer.

On the other hand, [esp+offset] is a longer instruction than [ebp+offset] so frame pointer elimination doesn't always generate shorter code.

• Are you sure about the 32-bit opcodes being shorter? In 16-bit mode, there are explicit encodings for the combinations of BX/BP, SI/DI, and an 8 or 16-bit displacement, and other variants aren’t encodable; in 32-bit mode, the generic register encoding is used (EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI), except that 100b (usually ESP) is used to signify a SIB byte, and 101b (usually EBP) with no displacement is used to signify a 32-bit offset. MOV EAX, [EBX+9] takes 3 bytes, as does MOV EAX, [ECX+9]; with an additional register you need 4 bytes. – Stephen Kitt Sep 19 '18 at 18:22
• @StephenKitt: I stand corrected. The only one that is actually longer is [esp+x] – Joshua Sep 19 '18 at 18:27