C 如何确定保存在堆栈上的值?

C 如何确定保存在堆栈上的值?,c,linux,assembly,inline-assembly,system-calls,C,Linux,Assembly,Inline Assembly,System Calls,我正在做一些实验,希望能够看到在系统调用期间堆栈上保存了什么(用户登录进程的保存状态)。根据它显示,寄存器的各种值保存在堆栈指针的特定偏移处。下面是我一直试图用来检查堆栈上保存的内容的代码(这是在我创建的自定义系统调用中): 其中,值为无符号长字符串 到目前为止,该值不是预期值(它显示为ds的用户值保存了0) 我是否正确访问堆栈指针的偏移量 另一种可能是,我是否可以在内核中使用GDB之类的调试器来检查堆栈内容?我对调试没有太多的用途,也不知道如何调试内核中的代码。非常感谢您的帮助 请记住,x86

我正在做一些实验,希望能够看到在系统调用期间堆栈上保存了什么(用户登录进程的保存状态)。根据它显示,寄存器的各种值保存在堆栈指针的特定偏移处。下面是我一直试图用来检查堆栈上保存的内容的代码(这是在我创建的自定义系统调用中):

其中,值为无符号长字符串

到目前为止,该值不是预期值(它显示为ds的用户值保存了0)

我是否正确访问堆栈指针的偏移量


另一种可能是,我是否可以在内核中使用GDB之类的调试器来检查堆栈内容?我对调试没有太多的用途,也不知道如何调试内核中的代码。非常感谢您的帮助

请记住,x86_64代码通常会在寄存器中传递值(因为它的寄存器太多),所以堆栈中不会有任何内容。检查gcc中间输出(
-S
IIRC),并在程序集中查找
push


我不熟悉调试内核代码,但gdb绝对更适合以交互方式检查堆栈。

内联汇编比看起来更复杂。试图简要介绍GCC关注的问题:

  • 如果它修改处理器寄存器,则有必要将这些寄存器放在clobber列表中。需要注意的是,clobber列表必须包含直接(读显式)或间接(读隐式)更改的所有寄存器
  • 为了加强(1),条件运算和数学运算也会改变寄存器,更常见的是状态标志(零、进位、溢出等),因此您必须通过向clobber列表中添加“cc”来通知它
  • 如果修改不同的(随机读取)内存位置,则添加“内存”
  • 添加volatile关键字,如果它修改了输入/输出参数中未提及的内存 然后,您的代码变成:

    asm("movl 0x1C(%%esp), %0;"
        : "=r" (value)
        : /* no inputs :) */
        /* no modified registers */
    );
    
    输出参数不需要在clobber列表中,因为GCC已经知道它将被更改

    或者,由于您只需要ESP寄存器的值,因此可以避免这样做的所有痛苦:

    register int esp asm("esp");
    esp += 0x1C;
    

    这也许不能解决你的问题,但这是一条路要走。参考、检查和。

    无需在线组装。
    entry\u 32.S
    为系统调用推送到堆栈上的保存状态以
    struct pt\u regs
    的形式显示,您可以像这样获得指向它的指针(您需要直接或间接地包括
    和/或
    ):

    struct pt_regs*regs=任务pt_regs(当前)

    register int esp asm("esp");
    esp += 0x1C;