Semua jawaban sangat bagus. Tetapi di atas itu, saya ingin membagikan sebuah contoh.
Di bawah ini adalah program cpp kecil:
#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;
}
Sekarang, mari kita hasilkan perakitan kode di atas (dan saya hanya akan menempelkan bagian-bagian dari perakitan yang relevan di sini):
Perintah untuk menghasilkan perakitan:
g++ -S -O3 -c -fverbose-asm -Wa,-adhln assembly.cpp
Dan majelis:
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
Anda dapat melihat dalam rakitan bahwa kode rakitan tidak dibuat sprintfkarena kompiler berasumsi bahwa xtidak akan berubah di luar program. Dan sama halnya dengan whileloop. whileloop sama sekali dihapus karena optimasi karena kompilator melihatnya sebagai kode yang tidak berguna dan dengan demikian langsung ditugaskan 5ke x(lihat movl $5, x(%rip)).
Masalahnya terjadi ketika bagaimana jika proses / perangkat keras eksternal akan mengubah nilai xsuatu tempat antara x = 8;dan if(x == 8). Kami berharap elseblok berfungsi, tetapi sayangnya kompiler telah memangkas bagian itu.
Sekarang, untuk menyelesaikan ini, di assembly.cpp , mari kita ubah int x;untuk volatile int x;dan cepat melihat kode assembly yang dihasilkan:
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
Di sini Anda dapat melihat bahwa kode perakitan untuk sprintf, printfdan whileloop dihasilkan. Keuntungannya adalah jika xvariabel diubah oleh beberapa program eksternal atau perangkat keras, sprintfbagian dari kode akan dieksekusi. Dan juga demikianwhile loop dapat digunakan untuk menunggu sibuk sekarang.