程序计数器是否总是需要改变(在指令滴答时)?
来自 程序计数器是否始终必须改变(在时钟滴答时)?,我已经知道 PC 不必在每个时钟都改变;因为一条特定指令可能需要多个时钟周期来执行。
我想进一步讨论这个问题。假设我们有以下简单的 C 代码:
// gcc -g min.c -o min.exe # generate executable
// gcc -S min.c -o min.s # generate assembler listing from source
// objdump -S min.exe > min.sdump # generate assembler listing from executable
int main() {
int a;
a = 15;
return a;
}
通过比较汇编程序列表(objdump -S
并不总是非常准确地散布源代码行),我得到如下信息:
min.s: min.sdump:
--------------------- -------------------------
main: 08048394 <main>:
pushl %ebp 8048394: 55 push %ebp
movl %esp, %ebp 8048395: 89 e5 mov %esp,%ebp
subl $16, %esp 8048397: 83 ec 10 sub $0x10,%esp
movl $15, -4(%ebp) 804839a: c7 45 fc 0f 00 00 00 movl $0xf,-0x4(%ebp)
movl -4(%ebp), %eax 80483a1: 8b 45 fc mov -0x4(%ebp),%eax
leave 80483a4: c9 leave
ret 80483a5: c3 ret
.size main, .-main 80483a6: 90 nop
我知道这很可能是错误的- 但我们假设一字节指令需要一个时钟周期,而其他指令则需要两个时钟周期。然后,我可以将“指令滴答”视为“前一个”命令完成后的时钟上升沿;如下时序图所示(对应反汇编清单;图像的 Latex/Tikz 代码可以在 这里):
所以解释一下原来的问题:
... PC(程序计数器)是否总是需要更改(在每个新指令滴答时)?
我在想,如果一条指令设置了PC(或者更确切地说是下一个PC),那么下一个执行地址与其当前地址相同,那么就无法退出该循环(当然,除非有一些外部中断)?
From Does the program counter always have to change (upon a clock tick)?, I already know that the PC does not have to change at each clock; as a particular instruction may take more than one clock tick to execute.
I'd like to further that question a bit. Let's say we have the following simple C code:
// gcc -g min.c -o min.exe # generate executable
// gcc -S min.c -o min.s # generate assembler listing from source
// objdump -S min.exe > min.sdump # generate assembler listing from executable
int main() {
int a;
a = 15;
return a;
}
By comparing the assembler listings (objdump -S
doesn't always intersperse source lines very accurately), I get something like this:
min.s: min.sdump:
--------------------- -------------------------
main: 08048394 <main>:
pushl %ebp 8048394: 55 push %ebp
movl %esp, %ebp 8048395: 89 e5 mov %esp,%ebp
subl $16, %esp 8048397: 83 ec 10 sub $0x10,%esp
movl $15, -4(%ebp) 804839a: c7 45 fc 0f 00 00 00 movl $0xf,-0x4(%ebp)
movl -4(%ebp), %eax 80483a1: 8b 45 fc mov -0x4(%ebp),%eax
leave 80483a4: c9 leave
ret 80483a5: c3 ret
.size main, .-main 80483a6: 90 nop
I know this is most likely wrong - but let's take that the one-byte instructions take one clock tick, and the others take two. Then, I could take the "instruction tick" to be the rising clock edge at the time after "the previous" command has finished; as shown the following timing diagram (corresponding to the disassembly listing; Latex/Tikz code for image can be found here):
So to paraphrase the original question:
... Does the PC (program counter) always have to change (upon each new instruction tick)?
I was thinking, if an instruction set the PC (or rather next PC), so the next execution address is same as its current one, there would be no way to exit that loop (unless there is some extern interrupt, of course)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所以这个小程序会做你所要求的:
它编译成这样的东西:
效果是,从外部看时,PC将保持不变。在芯片内部,一步会执行类似的操作:
PC 将被设置,但始终保持与当前相同的值。
编辑
目前尚不清楚“锁定”的确切含义。 每个无限循环都会消耗CPU资源,并且如果禁用中断则不会被中断。这与PC是否改变无关。上面的循环只是可能的最小紧密循环。
然而:在真实的系统上,存在ARE中断 - 在每个值得这两个字母的操作系统上,调度程序将被定时器中断唤醒,并将CPU交给下一个进程。即使在通常没有“操作系统”的微控制器上,在每种重要情况下也会使用内部和外部中断。事实上 - 上面的紧密循环在微控制器上并不罕见 - 主要工作已完成,CPU 进入紧密循环并等待下一个中断。中断会以某种方式打破循环。
请注意,在真实的操作系统上,仅仅一个用户空间程序无法直接控制中断,正是出于这个原因:否则任何愚蠢的程序都可能通过一个汇编命令使系统瘫痪。
So this small program would do what you ask for:
It compile into something like this:
The effect is, that the PC will stay the same when looking from the outside. On the inside the silicon will do something like this in one step:
The PC will be set but always to the same value as it is currently.
Edit
It is not clear what you mean exactly with "lock". Every endless loop will will eat CPU resources and will be uninterruptible if interrupts are disabled. This has nothing to do whether the PC changes or not. The loop from above is only the smallest tight loop possible.
However: On real systems there ARE interrupts - on every OS worth these two letters the scheduler will be woken up by a timer interrupt and give the CPU to the next process. Even on a microcontroller where there is usually no "operating system" internal and external interrupts are used in every non-trivial case. In fact - the tight loop from above is not uncommon on microcontrollers - the main job is done, the CPU goes into a tight loop and wait for the next interrupt. The interrupt will somehow break the loop.
Please note, that on a real OS a mere user space program has no direct control over the interrupts for exactly that reason: Otherwise any stupid program could bring the system down with one assembler command.
你所描述的是一个无限循环 - 例如,通过跳转到自身,PC基本上会“保持不变”并且永远不会退出 - 除了一些外部事件(例如关闭计算机或从外部引发中断......)。 PC是否在技术上/间歇性地改变取决于特定处理器如何实现所使用的指令......
what you describe is an endless loop - for example by jumping to itself the PC would basically "stay the same" and never exit - except for some external event (like turning off the computer or raising an interrupt externally...). Whether PC is technically/intermittantly changed depends on how the specific processor implements the used instruction...