You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在GDB中使用set命令修改变量时如何正确转换类型?

问题:GDB通过变量名修改GNU汇编程序变量失败

调试GNU汇编(GAS)程序时,尝试用变量名通过GDB的set命令修改变量值遇到以下问题:

  • 执行set constant = 666,GDB提示:'constant' has unknown type; cast it to its declared type
  • 添加类型转换后执行set (int) constant = 666,报错:Left operand of assignment is not an lvalue
  • 仅能通过变量地址set *0x804a000 = 666完成修改,希望直接用变量名操作。

GDB交互记录

(peter)-[~/ri/rfe/p88]
$ gdb -q moving_data_between_registers_and_memory
Reading symbols from moving_data_between_registers_and_memory...
(No debugging symbols found in moving_data_between_registers_and_memory)
(gdb) br _start 
Breakpoint 1 at 0x8049000
(gdb) r
Starting program: /home/peter/Documents/.../moving_data_between_registers_and_memory 
zshenv

Breakpoint 1, 0x08049000 in _start ()
(gdb) print constant 
'constant' has unknown type; cast it to its declared type
(gdb) print (int) constant 
$1 = 10
(gdb) si
0x08049001 in mov_immediate_data_between_registers_and_memory
    ()
(gdb) si
0x08049006 in mov_immediate_data_between_registers_and_memory
    ()
(gdb) si
0x0804900b in exit ()
(gdb) print (int) constant 
$2 = 777
(gdb) set constant = 666
'constant' has unknown type; cast it to its declared type
(gdb) set (int) constant = 666
Left operand of assignment is not an lvalue.
(gdb) print &constant 
$3 = (<data variable, no debug info> *) 0x804a000
(gdb) set *0x804a000 = 666
(gdb) print (int) constant 
$4 = 666
(gdb) 

汇编源码

#moving_data_between_registers_and_memory:  mov data between regs and mem


.section .data
#.section .bss
   constant:
        .int 10
#       .int 0

.section .text
   .globl _start

_start:
   nop                  #used for debugging purposes

mov_immediate_data_between_registers_and_memory:
   movl $777, %eax      #mov immediate value 777 to eax
   movl %eax, constant  #mov eax value into constant mem value

exit:
   movl $1, %eax        #sys_exit system call
   movl $0, %ebx        #exit code 0 successful execution
   int $0x80

解决方案

方案1:编译时生成调试符号

问题根源是编译时未生成调试信息,GDB无法识别变量的类型和存储属性。编译时添加-g参数生成调试符号:

as -g moving_data_between_registers_and_memory.s -o moving_data_between_registers_and_memory.o
ld moving_data_between_registers_and_memory.o -o moving_data_between_registers_and_memory

重新编译后,GDB能直接识别constant的类型,执行set constant = 666即可正常修改变量值。

方案2:GDB内手动指定变量类型(无需重新编译)

如果不想重新编译,可通过指针操作实现变量名修改:

  1. 直接通过地址转换赋值:
set variable *(int *)&constant = 666
  1. 先定义指针变量再赋值:
set $constant_ptr = (int *)&constant
set *$constant_ptr = 666

解释:(int)constant是将变量值转换为int类型(右值,无法赋值),而*(int *)&constant是先取变量地址、转换为int指针,再解引用得到可赋值的左值。


内容的提问来源于stack exchange,提问作者nostromo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:50:18