I know that an ARM instruction is 32 bits in size and therefore in memory it take up 4 memory locations (each location can store 8 bits)
But am confused on how a branch instruction address works
When using e.g. a Branch instruction
4 bits are used for the operation 4 bits for the condition 24 bits for where to branch
Why is an address 4 * 24 bits? - I thought every instruction address was 32 bits
what does it mean by the 24 bit number being an offset?
Such a branch instruction can only jump a distance of +/- 2^25 bytes from the current PC (26 bits for the jump, including the sign bit, minus two implied low-order zero bits, makes 24 bits).
If you want to jump further than that, you have to use e.g.
In the ARM architecture, the 32 bit instructions (or 16 bits for most Thumb state instructions) allow for 32 bits to encode both the instruction type and any operands used by that instruction.
Of these 32 bits, 4 are taken for conditional execution, leaving 28. Of the remaining 28 bits, 4 of these are taken to break down the instructions into groups. This leaves 24 bits which are allocated to either additional sub-division of instruction behavior, register selection, or immediate values (program data which is encoded directly into the instruction opcode.)
Since 8 bits are already allocated to these first 2 functions, the largest immediate value which is possible in the 32 bit architecture is 24 bits. As described in the other answers, the relative branch instruction defines this 24 bit field as being used as a signed offset from the current location. In the 16/32 bit thumb instruction set, the offset which is available in a similar instruction is a little smaller, but it is still true that a large proportion of all of the branches in any program tend to be small (so it is rare to need to rely on a core register to calculate/hold the branch address).
In the 64 bit architecture, there is a similar discrepancy. Although the instructions are still only 32 bits, instruction addresses are now greater than 32 bits so there are potentially more large offset branches. In practice, these are still not really any more common within a single program (but might come into play when the operating system is switching context between one program and another - in which case the specific addresses will be already stored in data memory rather than as part of the instructions).
From the ARM7TDMI manual:
Offset in this case means that it's relative to the current
PC
.The reason the offset is shifted by 2 bits (i.e. multiplied by 4) is that every instruction is required to be word aligned, i.e. instructions have to be located at an address that is a multiple of 4. The two least significant bits of all such addresses are always zero. Since you know that they are always zero you can store a 26-bit offset in 24 bits by omitting those two least significant bits.