当我在 gdb 中使用“disas”指令反汇编 RISC-V 指令时,它会显示以下内容:
li a0,64
我希望它显示十六进制立即数,而不是十进制。例如
li a0,0x40
是否可以在 RISC-V 的 GBD 中执行此操作?
(我猜测 gdb 强制采用十进制,因此它可以以十进制而不是十六进制显示带符号的负值(这可能会让某些人感到困惑),但我只是想以防万一来配置它。)
最佳答案
没有。
GDB 使用的 risc-v 反汇编程序没有将立即数格式化为十六进制的选项。
但是,使用当前开发(未发布)版本的 GDB 可能可以完成您想要的操作。
自 GDB 13 起,有一个包装反汇编器的 Python API。 GDB 13 中存在的版本非常基础,并不能像您希望的那样为您提供帮助。然而,这个 API 在开发分支中得到了扩展,因此应该可以编写一个 Python 脚本来按照您想要的方式重新格式化立即数。
这是一个初始脚本,将其保存到文件 riscv-dis.py
中:
请记住,这仅适用于 GDB 14,或使用 GDB 当前的开发分支。
import gdb.disassembler
class riscv_dec_imm_disasm(gdb.disassembler.Disassembler):
def __init__(self):
super().__init__("riscv_dec_imm_disasm")
def __call__(self, info):
result = gdb.disassembler.builtin_disassemble(info)
parts = []
for p in result.parts:
if (
isinstance(p, gdb.disassembler.DisassemblerTextPart)
and (
p.style == gdb.disassembler.STYLE_IMMEDIATE
or p.style == gdb.disassembler.STYLE_ADDRESS_OFFSET
)
and p.string[0:2] != "0x"
):
# An immediate part that does not have '0x' prefix, so
# should be decimal. Lets reformat it as hex.
#
# TODO: This assumes that all immediates are 8-bits,
# which isn't going to be correct. I guess you'll
# need to map from mnemonic to immediate size in order
# to do this correctly.
v = int(p.string)
parts.append(info.text_part(p.style, ("0x%x" % (v & 0xFF))))
else:
# Don't change this part.
parts.append(p)
return gdb.disassembler.DisassemblerResult(length=result.length,
parts=parts)
gdb.disassembler.register_disassembler(riscv_dec_imm_disasm())
然后我们可以在 GDB session 中使用它,如下所示:
$ gdb -q /tmp/hello.rv32imc.x
Reading symbols from /tmp/hello.rv32imc.x...
(gdb) disassemble main
Dump of assembler code for function main:
0x000101aa <+0>: add sp,sp,-16
0x000101ac <+2>: sw ra,12(sp)
0x000101ae <+4>: sw s0,8(sp)
0x000101b0 <+6>: add s0,sp,16
0x000101b2 <+8>: lui a5,0x18
0x000101b4 <+10>: add a0,a5,1756 # 0x186dc
0x000101b8 <+14>: jal 0x1040e <puts>
0x000101ba <+16>: li a7,7
0x000101bc <+18>: li a6,6
0x000101be <+20>: li a5,5
0x000101c0 <+22>: li a4,4
0x000101c2 <+24>: li a3,3
0x000101c4 <+26>: li a2,2
0x000101c6 <+28>: li a1,1
0x000101c8 <+30>: li a0,0
0x000101ca <+32>: jal 0x1014c <call_me>
0x000101cc <+34>: li a5,0
0x000101ce <+36>: mv a0,a5
0x000101d0 <+38>: lw ra,12(sp)
0x000101d2 <+40>: lw s0,8(sp)
0x000101d4 <+42>: add sp,sp,16
0x000101d6 <+44>: ret
End of assembler dump.
(gdb) source riscv-dis.py
(gdb) disassemble main
Dump of assembler code for function main:
0x000101aa <+0>: add sp,sp,0xf0
0x000101ac <+2>: sw ra,0xc(sp)
0x000101ae <+4>: sw s0,0x8(sp)
0x000101b0 <+6>: add s0,sp,0x10
0x000101b2 <+8>: lui a5,0x18
0x000101b4 <+10>: add a0,a5,0xdc
0x000101b8 <+14>: jal 0x1040e <puts>
0x000101ba <+16>: li a7,0x7
0x000101bc <+18>: li a6,0x6
0x000101be <+20>: li a5,0x5
0x000101c0 <+22>: li a4,0x4
0x000101c2 <+24>: li a3,0x3
0x000101c4 <+26>: li a2,0x2
0x000101c6 <+28>: li a1,0x1
0x000101c8 <+30>: li a0,0x0
0x000101ca <+32>: jal 0x1014c <call_me>
0x000101cc <+34>: li a5,0x0
0x000101ce <+36>: mv a0,a5
0x000101d0 <+38>: lw ra,0xc(sp)
0x000101d2 <+40>: lw s0,0x8(sp)
0x000101d4 <+42>: add sp,sp,0x10
0x000101d6 <+44>: ret
End of assembler dump.
(gdb)
这有一个大问题——为了将负立即数显示为 0xfff...我需要将立即数屏蔽为大小,这意味着我需要知道立即数有多大。知道这一点的唯一方法是根据(我猜)指令助记符查找立即大小。在上面的脚本中,我假设所有立即数都是 8 位。
关于ubuntu - 是否可以在 gdb 中更改反汇编中的立即数是否以十六进制与十进制显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76918384/