सभी उत्तर उत्कृष्ट हैं। लेकिन उसके शीर्ष पर, मैं एक उदाहरण साझा करना चाहूंगा।
नीचे एक छोटा सा कार्यक्रम है:
#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;
}
अब, उपरोक्त कोड की असेंबली को जेनरेट करने देता है (और मैं असेंबली के केवल वही हिस्से पेस्ट करूंगा जो यहां प्रासंगिक हैं):
विधानसभा बनाने की आज्ञा:
g++ -S -O3 -c -fverbose-asm -Wa,-adhln assembly.cpp
और विधानसभा:
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
आप असेंबली में देख सकते हैं कि असेंबली कोड sprintf
इसलिए जेनरेट नहीं किया गया था क्योंकि कंपाइलर ने मान लिया था कि x
वह प्रोग्राम के बाहर नहीं बदलेगा। और while
लूप के मामले में भी ऐसा ही है । while
अनुकूलन के कारण लूप को पूरी तरह से हटा दिया गया क्योंकि संकलक ने इसे एक बेकार कोड के रूप में देखा और इस तरह सीधे (देखें ) 5
को सौंपा ।x
movl $5, x(%rip)
समस्या तब होती है जब कोई बाहरी प्रक्रिया / हार्डवेयर x
कहीं x = 8;
और के बीच के मूल्य को बदल देता है if(x == 8)
। हम else
काम करने के लिए ब्लॉक की उम्मीद करेंगे लेकिन दुर्भाग्य से संकलक ने उस हिस्से को छंटनी कर दी है।
अब, इसे हल करने के लिए assembly.cpp
, हमें विधानसभा कोड को जेनरेट int x;
करने के लिए volatile int x;
जल्दी से बदल कर देखें:
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
यहाँ आप देख सकते हैं कि के लिए विधानसभा कोड sprintf
, printf
और while
पाश उत्पन्न किया गया। लाभ यह है कि अगर x
चर को किसी बाहरी प्रोग्राम या हार्डवेयर द्वारा बदल दिया जाता है, sprintf
तो कोड का हिस्सा निष्पादित किया जाएगा। और इसी तरह while
लूप का उपयोग अब व्यस्त प्रतीक्षा के लिए किया जा सकता है।