Tüm cevaplar mükemmel. Ama bunun da ötesinde, bir örnek paylaşmak istiyorum.
Aşağıda küçük bir cpp programı var:
#include <iostream>
int x;
int main(){
char buf[50];
x = 8;
if(x == 8)
printf("x is 8\n");
else
sprintf(buf, "x is not 8\n");
x=1000;
while(x > 5)
x--;
return 0;
}
Şimdi, yukarıdaki kodun derlemesini oluşturalım (ve yalnızca derlemenin burada ilgili olan bölümlerini yapıştıracağım):
Montaj oluşturma komutu:
g++ -S -O3 -c -fverbose-asm -Wa,-adhln assembly.cpp
Ve meclis:
main:
.LFB1594:
subq $40, %rsp #,
.seh_stackalloc 40
.seh_endprologue
# assembly.cpp:5: int main(){
call __main #
# assembly.cpp:10: printf("x is 8\n");
leaq .LC0(%rip), %rcx #,
# assembly.cpp:7: x = 8;
movl $8, x(%rip) #, x
# assembly.cpp:10: printf("x is 8\n");
call _ZL6printfPKcz.constprop.0 #
# assembly.cpp:18: }
xorl %eax, %eax #
movl $5, x(%rip) #, x
addq $40, %rsp #,
ret
.seh_endproc
.p2align 4,,15
.def _GLOBAL__sub_I_x; .scl 3; .type 32; .endef
.seh_proc _GLOBAL__sub_I_x
Derlemede derleme kodunun oluşturulmadığını görebilirsiniz, sprintfçünkü derleyici xprogramın dışında değişmeyeceğini varsaymıştır . Aynı şey whiledöngü için de geçerlidir. whilederleyici bir işe yaramaz kod olarak gördüler ve böylece doğrudan atanmış çünkü döngü tamamen nedeniyle optimizasyonu çıkarıldı 5için x(bkz movl $5, x(%rip)).
Sorun, harici bir işlem / donanım ve ile xarasındaki bir yerde değerini değiştirirse oluşur . Bloğun çalışmasını beklerdik ama maalesef derleyici bu kısmı düzeltti.x = 8;if(x == 8)else
Şimdi, içeri, bu çözmek için assembly.cpp, bizi değiştirmesine izin int x;için volatile int x;ve hızlı bir şekilde oluşturulan derleme kod bakın:
main:
.LFB1594:
subq $104, %rsp #,
.seh_stackalloc 104
.seh_endprologue
# assembly.cpp:5: int main(){
call __main #
# assembly.cpp:7: x = 8;
movl $8, x(%rip) #, x
# assembly.cpp:9: if(x == 8)
movl x(%rip), %eax # x, x.1_1
# assembly.cpp:9: if(x == 8)
cmpl $8, %eax #, x.1_1
je .L11 #,
# assembly.cpp:12: sprintf(buf, "x is not 8\n");
leaq 32(%rsp), %rcx #, tmp93
leaq .LC0(%rip), %rdx #,
call _ZL7sprintfPcPKcz.constprop.0 #
.L7:
# assembly.cpp:14: x=1000;
movl $1000, x(%rip) #, x
# assembly.cpp:15: while(x > 5)
movl x(%rip), %eax # x, x.3_15
cmpl $5, %eax #, x.3_15
jle .L8 #,
.p2align 4,,10
.L9:
# assembly.cpp:16: x--;
movl x(%rip), %eax # x, x.4_3
subl $1, %eax #, _4
movl %eax, x(%rip) # _4, x
# assembly.cpp:15: while(x > 5)
movl x(%rip), %eax # x, x.3_2
cmpl $5, %eax #, x.3_2
jg .L9 #,
.L8:
# assembly.cpp:18: }
xorl %eax, %eax #
addq $104, %rsp #,
ret
.L11:
# assembly.cpp:10: printf("x is 8\n");
leaq .LC1(%rip), %rcx #,
call _ZL6printfPKcz.constprop.1 #
jmp .L7 #
.seh_endproc
.p2align 4,,15
.def _GLOBAL__sub_I_x; .scl 3; .type 32; .endef
.seh_proc _GLOBAL__sub_I_x
Burada sprintf, printfve whileloop için derleme kodlarının oluşturulduğunu görebilirsiniz. Avantajı, xdeğişken bazı harici program veya donanım tarafından değiştirilirse sprintf, kodun bir kısmının yürütülmesidir. Ve benzer şekilde whiledöngü şimdi meşgul beklemek için kullanılabilir.