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 804开发者_运维百科83a6: 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)?
So this small program would do what you ask for:
int main(){
loop: goto loop;
}
It compile into something like this:
.L3:
jmp .L3
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:
PC = argument of JMP
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.
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...
精彩评论