问题
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
?
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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
来源:https://stackoverflow.com/questions/29737035/can-someone-explain-the-branch-opcode-in-arm