Skip to main content

This is obviously more space-efficient (one byte for the opcode, and one byte for the 8-bit offset versus one byte for the opcode and two bytes for a 16-bit absolute address), but also (perhaps less obviously) more time-efficient when averaged out: a branch not taken is only two cycles (to read the opcode adand offset) with the relative address, but still three cyles with an absolute address. (Taken is three cycles in both cases. The one exception is that a taken relative branch needs four cycles when it crosses a page boundary, due to the need for a second add for the carry from the low byebyte of the address, but that's relatively infrequent.)

This is obviously more space-efficient (one byte for the opcode, one byte for the 8-bit offset versus one byte for the opcode and two bytes for a 16-bit absolute address), but also (perhaps less obviously) more time-efficient when averaged out: a branch not taken is only two cycles (to read the opcode ad offset) with the relative address, but still three cyles with an absolute address. (Taken is three cycles in both cases. The one exception is that a taken relative branch needs four cycles when it crosses a page boundary, due to the need for a second add for the carry from the low bye of the address, but that's relatively infrequent.)

This is obviously more space-efficient (one byte for the opcode and one byte for the 8-bit offset versus one byte for the opcode and two bytes for a 16-bit absolute address), but also (perhaps less obviously) more time-efficient when averaged out: a branch not taken is only two cycles (to read the opcode and offset) with the relative address, but still three cyles with an absolute address. (Taken is three cycles in both cases. The one exception is that a taken relative branch needs four cycles when it crosses a page boundary, due to the need for a second add for the carry from the low byte of the address, but that's relatively infrequent.)

Space and time efficiency comparison between relative and absolute conditional branches
Source Link
cjs
  • 28k
  • 2
  • 83
  • 199

This is obviously more space-efficient (one byte for the opcode, one byte for the 8-bit offset versus one byte for the opcode and two bytes for a 16-bit absolute address), but also (perhaps less obviously) more time-efficient when averaged out: a branch not taken is only two cycles (to read the opcode ad offset) with the relative address, but still three cyles with an absolute address. (Taken is three cycles in both cases. The one exception is that a taken relative branch needs four cycles when it crosses a page boundary, due to the need for a second add for the carry from the low bye of the address, but that's relatively infrequent.)

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute address and taking the upper eight bits from the PC, effectively using "the current page,"), but that gets pretty complex for the programmer because you'd need to know about the absolute location of your code to avoid accidental jumps to the wrong page.¹

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute address and taking the upper eight bits from the PC, effectively using "the current page,"), but that gets pretty complex for the programmer because you'd need to know about the absolute location of your code to avoid accidental jumps to the wrong page.¹

This is obviously more space-efficient (one byte for the opcode, one byte for the 8-bit offset versus one byte for the opcode and two bytes for a 16-bit absolute address), but also (perhaps less obviously) more time-efficient when averaged out: a branch not taken is only two cycles (to read the opcode ad offset) with the relative address, but still three cyles with an absolute address. (Taken is three cycles in both cases. The one exception is that a taken relative branch needs four cycles when it crosses a page boundary, due to the need for a second add for the carry from the low bye of the address, but that's relatively infrequent.)

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute address and taking the upper eight bits from the PC, effectively using "the current page,"), but that gets pretty complex for the programmer because you'd need to know about the absolute location of your code to avoid accidental jumps to the wrong page.¹

Restore previous formatting, keeping "bytes" -> "bits" typo fixes
Source Link
cjs
  • 28k
  • 2
  • 83
  • 199

On the 6502, the designers did this for efficiency. This is documented in in the original MCS 6500 Microcomputer Family Programming Manual Manual:

If one considers that the instruction JMP required three bytes, one for OP CODE, one for new program counter low (PCL) and one for new program counter high (PCH) it is seen that jump on carry set would also require three bytes. Because most programs for control require many continual jumps or branches, the MCS650X uses "relative" addressing for all conditional test instructions. To perform any branch, the program counter must be changed. In relative addressing, however, we add the value in the memory location following the OP CODE to the program counter. This allows us to specify a new program counter location with only two bytes, one for the OP CODE and one for the value to be added. (§4.1.1 p. 38)

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute absolute address and taking the upper eight bits from the PC, effectively effectively using "the current page,"), but that gets pretty complex for for the programmer because you'd need to know about the absolute location location of your code to avoid accidental jumps to the wrong page.1¹

Another reason for having some sort of relative jumps is to allow creation creation of more easily relocatable code. Code that uses only relative jumps jumps can be copied to another location and "just work"; code with absolute absolute jumps must have those patched up for the new jump target locations locations. While having a limited set of relative branch instructions doesn't doesn't let you relocate arbitrary code, it still makes it easy to relocate relocate small routines, which is valuable. There are, for example, not not-infrequent cases where using self-modifying code on the 6502 can increase both speed and memory efficiency. Self-modifying code can't be be run from ROM, but if you can easily copy small routines from ROM to RAM RAM that opens up this technique for code intended to be in ROM.

Relocatable code wasn't a major priority on the 6502 (though I have little little doubt that the designers did have in mind some support for this from from the start—whatever they could fit in without adding cost to the design design), but it was for the 6809, where you noticed that they'd added long long branches. The MC6809 data sheet says in its very first paragraph paragraph that it "supports modern programming techniques such as position position independence," and later in the discussion of long and short relative relative branches, "Position-independent code can be easily generated through through the use of relative branching" (p. 20). Somewhere there's a larger larger discussion of Motorola's vision of building ROMs for specific machines from a large library of relocatable code, but I don't have a reference reference for that at the moment.


1 ¹ That's more complex than it sounds on some CPUs. Consider a branch in the last two bytes of a page on a 6502: that puts the PC on the next page before it's used to calculate the branch address. There are ways of working around this, too, such as considering addresses in the "other half" of the page to be in the previous or next page, as appropriate, but now you're piling complexity on complexity.

On the 6502, the designers did this for efficiency. This is documented in the original MCS 6500 Microcomputer Family Programming Manual:

If one considers that the instruction JMP required three bytes, one for OP CODE, one for new program counter low (PCL) and one for new program counter high (PCH) it is seen that jump on carry set would also require three bytes. Because most programs for control require many continual jumps or branches, the MCS650X uses "relative" addressing for all conditional test instructions. To perform any branch, the program counter must be changed. In relative addressing, however, we add the value in the memory location following the OP CODE to the program counter. This allows us to specify a new program counter location with only two bytes, one for the OP CODE and one for the value to be added. (§4.1.1 p. 38)

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute address and taking the upper eight bits from the PC, effectively using "the current page,"), but that gets pretty complex for the programmer because you'd need to know about the absolute location of your code to avoid accidental jumps to the wrong page.1

Another reason for having some sort of relative jumps is to allow creation of more easily relocatable code. Code that uses only relative jumps can be copied to another location and "just work"; code with absolute jumps must have those patched up for the new jump target locations. While having a limited set of relative branch instructions doesn't let you relocate arbitrary code, it still makes it easy to relocate small routines, which is valuable. There are, for example, not-infrequent cases where using self-modifying code on the 6502 can increase both speed and memory efficiency. Self-modifying code can't be run from ROM, but if you can easily copy small routines from ROM to RAM that opens up this technique for code intended to be in ROM.

Relocatable code wasn't a major priority on the 6502 (though I have little doubt that the designers did have in mind some support for this from the start—whatever they could fit in without adding cost to the design), but it was for the 6809, where you noticed that they'd added long branches. The MC6809 data sheet says in its very first paragraph that it "supports modern programming techniques such as position independence," and later in the discussion of long and short relative branches, "Position-independent code can be easily generated through the use of relative branching" (p. 20). Somewhere there's a larger discussion of Motorola's vision of building ROMs for specific machines from a large library of relocatable code, but I don't have a reference for that at the moment.


1 That's more complex than it sounds on some CPUs. Consider a branch in the last two bytes of a page on a 6502: that puts the PC on the next page before it's used to calculate the branch address. There are ways of working around this, too, such as considering addresses in the "other half" of the page to be in the previous or next page, as appropriate, but now you're piling complexity on complexity.

On the 6502, the designers did this for efficiency. This is documented in the original MCS 6500 Microcomputer Family Programming Manual:

If one considers that the instruction JMP required three bytes, one for OP CODE, one for new program counter low (PCL) and one for new program counter high (PCH) it is seen that jump on carry set would also require three bytes. Because most programs for control require many continual jumps or branches, the MCS650X uses "relative" addressing for all conditional test instructions. To perform any branch, the program counter must be changed. In relative addressing, however, we add the value in the memory location following the OP CODE to the program counter. This allows us to specify a new program counter location with only two bytes, one for the OP CODE and one for the value to be added. (§4.1.1 p. 38)

It would be possible to try to achieve this with partial absolute addresses (e.g., by specifying only the lower eight bits of the absolute address and taking the upper eight bits from the PC, effectively using "the current page,"), but that gets pretty complex for the programmer because you'd need to know about the absolute location of your code to avoid accidental jumps to the wrong page.¹

Another reason for having some sort of relative jumps is to allow creation of more easily relocatable code. Code that uses only relative jumps can be copied to another location and "just work"; code with absolute jumps must have those patched up for the new jump target locations. While having a limited set of relative branch instructions doesn't let you relocate arbitrary code, it still makes it easy to relocate small routines, which is valuable. There are, for example, not-infrequent cases where using self-modifying code on the 6502 can increase both speed and memory efficiency. Self-modifying code can't be run from ROM, but if you can easily copy small routines from ROM to RAM that opens up this technique for code intended to be in ROM.

Relocatable code wasn't a major priority on the 6502 (though I have little doubt that the designers did have in mind some support for this from the start—whatever they could fit in without adding cost to the design), but it was for the 6809, where you noticed that they'd added long branches. The MC6809 data sheet says in its very first paragraph that it "supports modern programming techniques such as position independence," and later in the discussion of long and short relative branches, "Position-independent code can be easily generated through the use of relative branching" (p. 20). Somewhere there's a larger discussion of Motorola's vision of building ROMs for specific machines from a large library of relocatable code, but I don't have a reference for that at the moment.


¹ That's more complex than it sounds on some CPUs. Consider a branch in the last two bytes of a page on a 6502: that puts the PC on the next page before it's used to calculate the branch address. There are ways of working around this, too, such as considering addresses in the "other half" of the page to be in the previous or next page, as appropriate, but now you're piling complexity on complexity.

fix typos
Source Link
Dave Tweed
  • 1.9k
  • 1
  • 10
  • 16
Loading
Source Link
cjs
  • 28k
  • 2
  • 83
  • 199
Loading