Kyl*_*yle 10 c cpu assembly gdb
当我学习汇编时,我使用GDB的方式如下:
gdb ./a.out (a is a compiled C script that only prints hello world)
break main
run
info registers
Run Code Online (Sandbox Code Playgroud)
当我自己使用相同的CPU打印寄存器时,为什么我可以看到程序使用的寄存器?不应该使用GDB(或操作系统)覆盖寄存器,只显示覆盖的寄存器?我能想到的唯一答案是我的CPU是双核的,其中一个内核正在使用,另一个是为程序保留的.
Jes*_*ter 15
操作系统维护每个执行线程的寄存器状态.当您检查gdb中的寄存器时,调试器实际上是要求操作系统从保存的状态读取寄存器值.你的程序在那个时间点没有运行,它是调试器.
假设您的系统上没有其他进程.以下是发生的事情的简化视图:
请注意,此机制是多任务操作系统的正常职责的一部分,它不是特定于调试.当OS调度程序决定应该执行另一个程序时,它会保存当前状态并加载另一个程序.这称为上下文切换,它可能每秒发生多次,给人一种错觉,即即使你只有一个cpu核心,程序也会同时执行.
在过去的单任务操作系统中,唯一可能阻碍程序执行的因素是中断.现在,中断处理程序遇到的问题与你所说的相同,你的程序正在计算某些东西,用户按下一个键 - 中断 - 中断服务程序必须做一些工作,但不能修改过程中的单个寄存器.这是主要原因,堆栈是首先发明的.通常的80x86 DOS中断服务程序如下所示:
push ax
push cx
push dx
push bx
push si
push di
push bp
// no need to push sp
[do actual work, caller registers avaiable on stack if needed]
pop bp
pop di
pop si
pop bx
pop dx
pop cx
pop ax
iret
Run Code Online (Sandbox Code Playgroud)
这甚至是如此常见,以至于创建了一个新的指令对pusha和popa(用于push/pop all)以简化此任务.
在今天的操作系统和应用程序之间具有地址空间隔离的CPU中,CPU提供一些任务状态系统并允许操作系统切换任务(中断可能仍然类似于上面概述的工作,但也可以通过任务切换来处理).所有现代操作系统都使用这个任务状态系统的系统,其中CPU在没有被主动执行时保存进程的所有寄存器.就像Jester已经解释的那样,gdb只是询问操作系统在要调试的进程上的这些值,然后打印它们.
| 归档时间: |
|
| 查看次数: |
575 次 |
| 最近记录: |