简体   繁体   中英

ARM Assembly TBB Instruction - how does jumping work?

so I'm trying to understand how TBB works for switch statements in Assembly. I see how it's written in the textbook/online manual, but I don't understand how the offsets work in the branch table. How does it go from branch table to instruction? How are labels subtracted to get the correct offset, and why divide by 2?

In my textbook it says

The memory address of the instruction to which the program should branch is calculated as follows:
target = PC + 4 + ( 2*BranchTable[r0] )

Where r0 is the counter containing the offset within the branch table. At TBB, PC already points to the next instruction (branch table, which is PC = PC+4). The branch table supposedly loads a second offset to the proper instruction (2*BranchTable[r0]). From what I've seen in my textbook and online, the branch table label is subtracted from the instruction label. This should give an offset of something like 4n. Why divide by 2? Thank you!

Edit: Did some math

So I did some math and it turns out that the offset in the branch table is [ (label2 - label1)/2]. Plugged into the equation earlier gives target = PC + 4 + (label 2 - label). This makes sense, but I'd still like to know if anyone has the reason why, or if my logic is wrong - why is TBB set up to divide by 2/multiply the difference by 2?

TBB / TBH are only available in Thumb2 mode.

ARM Thumb2 instructions always start on an even address. Being able to branch to PC+4 + {0, 2, 4, 6, 8, ..., 508, 510} is more useful than
PC+4 + {0, 1, 2, 3, 4, ..., 254, 255 } , because all the odd offsets are useless. As @Jester explained in the first comment , multiplying by 2 gives you twice the range from one-byte offsets with no loss in flexibility.

ARM's designers could have designed it to always multiply by 4, but 512B is generally enough range, and it would sometimes require padding the code blocks to be multiples of 4 bytes long. If larger offsets are needed, TBH uses half-word 16-bit offsets (still multiplied by 2).

Here's a real example of a jump table using TBB, with the raw hex and commented disassembly working out the math of how each branch target was reached (like
case 3: (0x3164 + 0x9 * 2) ): Confused by TBB in a section of ARM disassembly

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM