GCC, C

2010-03-01 22 views
5

'daki deyimine devam etmek üzere derlemenin oluşturulmasına eşdeğerdir C kodunda bir döngü içinde bir devam ifadesi kullanıldığında, GCC, döngü bloğunun sonundan hemen önce nop komutuyla yeni bir etiket oluşturur ve atlamak yerine atlar. döngü bloğunun sonuna kadar. Örneğin,GCC, C

for (i=0; i<10; i++) { 
    puts("blah\n"); 
    if (i < 10) continue; 
    puts("This shouldn't be printed.\n"); 
} 

aşağıdaki ASM eşdeğer üreten aşağıdaki C kodu için (gcc -S kullanılarak):

movl $0, 28(%esp) 
    jmp L2 
L5: 
    movl $LC0, (%esp) 
    call _puts 
    cmpl $9, 28(%esp) 
    jle L7 
L3: 
    movl $LC1, (%esp) 
    call _puts 
    jmp L4 
L7: 
    nop 
L4: 
    incl 28(%esp) 
L2: 
    cmpl $9, 28(%esp) 
    jle L5 

(if (i derleyici kokan böylece 10) bir parçası sokulur < t "devam" ifadesini takip eden her şeyi kaldırarak bölümü "optimize et")

Soruma göre, neden doğrudan L4'e atlamıyorum? IMO, L4'e atlayabileceğimiz bir şey mi eksik?

cevap

4

Tanımladığınız şey bir optimizasyon. Şüphesiz, gcc'ye optimize etmesini söylerseniz (-O1 yeterlidir), açıkladığınız şeyi tam olarak yapar.

+0

Hızlı cevap için teşekkürler! -O1 hile yaptı, ancak optimizasyondan sonra program akışı biraz daha az sezgisel gibi gözüküyor - yanılmadıkça, döngü şimdi kısmen açık görünüyor. Şimdi nop talimatı ile etiket oluşturma konusunda herhangi bir teşvik olup olmadığını merak ediyorum. Bu yaklaşımın, doğrudan L4'e sıçraması halinde gerçekleşecek bir şeyi önleyeceği bir durum var mı? – susmits

+0

Hata ayıklama amacıyla, L7 etiketinde bir kesme noktası belirtebilirsiniz - orada olmadığında devam durumunda kırılması zor olurdu. – nos

+0

Susmits: -O1 ile montaj daha az ayrıntılıdır, ancak döngü açılmamış (-O3 ile açılmamış sürümü görebilirsiniz - i <10 kontrolünü veya 2. adımı() içeremez) . Genel olarak, etiket oluşturmak ve bu tür optimizasyonları gerçekleştirmemek hata ayıklamada çok yardımcı olur. –

1

Tahminimce, bir tür atla-kod düzeltme dizisi için bir yer tutucu olmasıdır. Belki de nop bazen yığındaki kayıtları veya bazılarını saklamak için yönergeler ile değiştirilir.

Ancak bununla ilgili daha fazla kanıt elde etmek için, nop'un başka bir şeyle değiştirildiği bir örnek bulmaya yardımcı olur.

+0

Sanırım bu muhtemelen bu. Bu durumda, "devam" ı yazmaçlardaki değişkenler dizisinin, ikinci konduktan sonra kayıttaki değişkenler kümesi ile aynı olduğu çok az değişken vardır. Durum böyle olmasaydı, L7 sonra onları senkronize etmek için kod olurdu. Döngüde birden çok "devam" olsaydı, elbette, her biri, elbette atlamadan önce kendini doğru L7 durumuna senkronize etmek zorunda kalırdı. –

+0

Diğer yandan, böyle bir kodu bir devam bildirimi ile ilişkili bir bloka yerleştirmek son derece verimsizdir, bu yüzden zaten oldukça nadir bir manzara olduğunu tahmin ediyorum. –

+0

Akılda tutulan akılsız verimsiz kodların (-O'nun belirtilmesiyle) talep edildiğini aklınızda bulundurun ;-) –