Can someone explain the branch opcode in ARM?
Asked Answered
M

4

7

I'm trying to create an opcode to jump to an address.

I looked in the manual and I see:

B<c> <label>

31 30 29 28 | 27 26 25 24 | 23 ................. 0
    cond      1  0  1  0          imm24

I don't understand what cond and imm24 are. How would I go about creating an opcode to branch to some address, for example branch to 0xbeffffbc?

Millisecond answered 19/4, 2015 at 23:17 Comment(0)
T
9

B is a relative branch of up to +/-32MB. The immediate encodes the signed offset of the target address from the current PC (i.e. this instruction + 8) - note that this offset is counted in words, not bytes; since instructions are always word-aligned, the bottom two bits of any offset will always be 00 and are thus made implicit in the encoding.

cond is the same predicate field as in most other ARM instructions. If you've got to the point of poking around instruction encodings you probably should be aware of that already - the "Conditional Execution" section of the ARM ARM (section A8.3 in the v7A/R edition I have handy) has the complete details.

The typical annoyance with the ARM ARM is that whilst the encoding fields and the values they represent are described in the instruction descriptions, you do sometimes have to cross-reference the pseudocode to figure out exactly what's going on.

Tuchman answered 19/4, 2015 at 23:40 Comment(3)
If I have my branch instruction at address 0xbeffffb0 and I want to jump to 0xbeffffbc then should it be branching +3?Millisecond
He said that the offset is counted in words. So I thought that meant in my example: I have 0xbeffffb0, 0xbeffffb4, 0xbeffffb8, oxbeffffbc in order. And I see that it is 3 words away?Millisecond
@Millisecond At 0xbeffffb0 the PC value will be 0xbeffffb8, so you'd actually encode +1 in the branch. It might become clearer if you inspect some disassembly - e.g. see that a b . infinite loop encodes an offset of -2 (amusingly, the same offset as for the equivalent operation on x86, but for an entirely different reason).Tuchman
B
1

On most architectures, imm is an immediate value (encoded in the actual instruction). Therefore, I would assume an imm24 is an immediate value that is 24 bits long. This imm value is usually signed.

Most jmp instructions are relative to the current Program Counter. This means that the immediate value encoded into the instruction is added to the program counter, which will point to the next instruction. If the imm value is negative, the value will be subtracted from the current program counter. Otherwise, the imm value will be added to the program counter.

To create a branch to your address 0xbeffffbc, you need to know the address of the current instruction and calculate the difference between them.

Bartel answered 19/4, 2015 at 23:39 Comment(0)
P
0

If your branch instruction is at 0xb0 and you want to jump to 0xbc the imm24 portion of your encoded instruction would have a value of 3.

This number 3 in your imm24 part of your instruction tells you [the number of instructions] you are moving from your current position to where you want to go.

The reason why imm24 encodes 3 and not 12 as you would expect (because branch is at 0xb0 and you want to be at 0xbc a difference of 12) is because the offset value encoded in imm24 is calculated using the value of the PC register, a value which is relative to the address branch is at (0xb0) which incidentally is not 0xb0 as you would think but 0xb8.

The value of your PC register is 2 instructions forward of the instruction address branch is at (due to pipelining) so the actual position of your branch instruction is at 0xb8 not 0xb0.

So ARM instructions have a size of 4 bytes and you are moving 3 instructions so 3 x 4 would give you 12 the difference of 0xb0 to 0xbc.

So if you wanted to format your instruction completely as per above

You would have an Opcode which tells the processor Branch is coming up (a specific value) then an optional condition (the cond part) which tells you under what condition it should make this branch, example if it was less than or more than and then the imm24 part as explained above which would form your complete instruction.

Plenum answered 20/4, 2015 at 1:40 Comment(0)
M
-1

Have a look at the ARM instruction set, you are searching for branch instructions. You can easily create labels and jump to them (jump to a specific place in the code), although I don't think it's what you wanna do.

If you want to jump to a memory address there are a bunch of methods for doing so (addressing modes). Immediate addressing, indirect addressing, ... Here you should find the instructions you are searching for : ARM branch instructions

You should really have a look on how the addressing works. It is crucial when programming in assembly to understand what it does.

Here you can find how the different addressing modes work : ARM addressing modes Summary of the different addressing modes

Basically you need to know you are in memory (nothing more or less than bits). So certain decisions have to be made about how to organize that memory. Certain parts or reserved for specific things.

With this memory you can easily build a stack, just by remembering the address of the topmost location (first free location, i.e SP (stack pointer)). Then you can use addresses relative to the stack pointer. That's also the way they implement procedure calls.

Information about the underlying working : Working of the stack

Molini answered 19/4, 2015 at 23:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.