2015-03-27 11 views
8

CS Architecture uygulamasında kısa ödevler için, aşağıdaki IA-32 aksamı C'ye tercüme edilmek üzere yapılmıştır. Doğruca tercüme ettiğimden emin olun (ama bildiğim kadarıyla) ama kod hiçbir şey yapmıyor gibi görünüyor. özellikle yararlıdır. Profesörüm genellikle bize böyle bir şeyle sonuçlanan bu gibi problemler verir: Bunun gibi son görevimiz biraz pop_count idi. Aşağıdaki C koduna bakarak, bu işlev yararlı bir şey yapar mı? Bazı algoritmalar belki?Bu tercüme edilmiş çeviri kodu parçası için daha büyük bir önemi var mı?

Kod aşağıdaki gibi görünüyor (her ASM hattına yorum ekledim).

// The following variables x, y, z are located at (%ebp) +8, +12, +16 respectively 
// x, y, and z, are scanned from the terminal and passed into the function 

    movl 12(%ebp), %edx     // moves long y to register %edx 
    subl 16(%ebp), %edx     // subtracts longs: y = y - z 
    movl %edx, %eax      // moves long y to register %eax 
    sall $31, %eax      // left shift all bits in long y by 31 places 
    sarl $31, %eax      // arithmetic right shift long y by 31 places 
    imull 8(%ebp), %edx     // multiply longs: unshifted y = y * x 
    xorl %edx, %eax      // XOR operation: shifted y = shifted y^unshifted y 

// The returned value is stored in register %eax 

etkili paket o zaman en az anlamlı biti ile her bit sıfıra veya MAX_UINT ya oluşturmak üzere doldurmak, y den z çıkarmak. Bu XOR'd (y - z) * x ürünü ile geri döndü ve geri döndü.

My çeviri C içine

: açıklama için

return (((y - z) << 31) >> 31)^((y - z) * x); 

// In more words: 
    int f; 
    y -= z; 
    f = y << 31;      // These two lines populate all bits with the lsb 
    f = f >> 31;      // Effectively, if y-z is odd: f is ~0; else f is 0 
    y *= x; 
    return y^f; 

// Or, using people logic: 
    y -= z; 
    if (y % 2 == 0) return y * x; 
    return -(y * x) - 1; 

// If the y-z is odd, the result will be: -1 * ((y - z) * x) - 1 
// If the y-z is even, the result will be:    (y - z) * x 

, bu HW ödevin parçası değildir; Kodu tercüme ederek ödevi tamamladım, ancak başlamak için neden bize kodunu verdiğini bilmek istiyorum.

cevap

3

Tahminimce, profesörünüz dallardan kaçınmak için bit değiştirme/maskeleme işlemlerini nasıl kullanabileceğinizi göstermeye çalışıyordu. Makine koduna

numaralarını naif olarak tercüme etmek için koşullu bir dal talimatı kullanırsınız. Şubeler, özellikle de sıkı bir döngü içinde olduklarında kodunuzu önemli ölçüde yavaşlatabilir *. Montaj kodu ve önceki C kodunuz, y - z'un eşit olup olmadığını, ancak yalnızca aritmetik komutları kullanarak koşullu kullanma etkisine sahiptir.

* Bu gerçeği henüz bilmiyorsanız, this SO answer en sevdiğim resimlerden birine sahiptir.

+0

Yaptığınız ilginç bir nokta. Gerçekten de, profesörüm, şartlı dallanma olmadan mantık yürütme yeteneğini kısmen gösterdiğini belirtti. Cevap için teşekkürler! – SeniorShizzle

İlgili konular