GDB如何判断所打印的指令属于ARM或Thumb模式?含libc函数指令场景
Great question! When working with ARM/Thumb binaries (including libc functions) in GDB, there are several reliable ways to tell which instruction set the debugger is using for disassembly. Let's break this down step by step:
1. Check the Address Least Significant Bit (LSB)
ARM requires instructions to be 4-byte aligned, while Thumb uses 2-byte alignment. To signal the instruction set mode, Thumb function entry addresses are stored with the LSB set to 1—this is a convention handled by the linker and loader behind the scenes.
When you run x/[num]i [address] in GDB:
- If the displayed address ends in an odd number (e.g.,
0x76f12341 <printf+1>), GDB is disassembling Thumb instructions. The actual memory address is0x76f12340(LSB cleared), but the trailing 1 tells GDB to use Thumb mode. - If the address ends in an even number (e.g.,
0x76f12340 <printf>), GDB is using ARM mode.
2. Inspect Disassembly Output & Instruction Lengths
The syntax of instructions and address increments also give clear clues:
- ARM mode: Instructions are 32 bits long, so each subsequent instruction address increases by 4. Mnemonics use full ARM syntax (e.g.,
mov r0, #0x10). - Thumb mode: Most instructions are 16 bits (with 32-bit Thumb-2 extensions), so addresses typically increment by 2 (or 4 for 32-bit Thumb-2). Mnemonics often have subtle differences (e.g.,
movs r0, #0x10instead of plainmovfor immediate values).
Example Thumb disassembly:
(gdb) x/3i 0x8000401 0x8000401 <main+1>: movs r0, #0 0x8000403 <main+3>: bl 0x80003f0 <puts@plt> 0x8000407 <main+7>: bx lr
Example ARM disassembly:
(gdb) x/3i 0x8000400 0x8000400 <main>: mov r0, #0 0x8000404 <main+4>: bl 0x80003f0 <puts@plt> 0x8000408 <main+8>: bx lr
3. Check CPU Status (For Live Debugging)
If you're debugging a running process, you can confirm the current execution mode by checking the CPSR (Current Program Status Register):
- Run
info registers cpsrin GDB. - Look at the T bit (bit 5):
T=1means the CPU is in Thumb mode.T=0means the CPU is in ARM mode.
Example output:
(gdb) info registers cpsr cpsr 0x60000010 1610612752
Here, bit 5 is set (binary 0x60000010 has bit 5 as 1), so we're in Thumb mode.
4. Libc Function Specifics
When disassembling libc functions with x/[num]i [libc_func]:
- GDB relies on the binary's ELF metadata (symbol tables, section attributes) to know if the function was compiled for ARM or Thumb.
- Most modern embedded/mobile systems use Thumb-optimized libc builds to save memory, so you'll likely see addresses with LSB=1 and 16/32-bit Thumb instructions.
- Legacy ARM-only libc builds will have even-aligned addresses and 32-bit ARM instructions.
内容的提问来源于stack exchange,提问作者Narc Eritor

