2016-04-10 37 views
-1

C kodumu MIPS düzeneğine çevirmeyi içeren sınıflarımdan biri için bir proje üzerinde çalışıyorum. Bu kod çeviri sorun olan am:Erişim numarası kime başka bir kayıtta saklanır

r[extract(ir,15,11)] = aluout; 

Temel olarak, r [] o extract işlevinden sonucuna dayalı erişim için kayıt belirler, Görüldüğü gibi C. kayıtları temsil eden bir dizidir. MIPS'de böyle bir şey var mı? Bunu yapmayı düşünebilmemin tek yolu, ekstrakt altprogramından geri alacağım değeri alıp, tüm kayıt numaralarına karşı kontrol etmektir. Bunun C gösterimi şöyle görünecektir:

regNum = extract(ir, 15, 11); 
if (regNum == 1) { 
    r[1] = aluout; 
} else if (regNum == 2) { 
    r[2] = aluout; 
} else if (regNum == 3) { 
    r[3] = aluout; 
} ... 

Herhangi bir fikir? Bu konuda gitmenin tek yolu bu mu?

+1

Umm, bir diziyi dizine ekleyebilirsiniz. Yine de ham kayıtları indeksleyemezsiniz. – Jester

+0

Evet biliyorum. C kodu, profesörümüzün MIPS'ye çevireceğimiz bir şey olduğunu söyledi. r [index] sadece MIPS – wKavey

+3

'a çevirecekseniz $ [index] registerini temsil eder. Yani bir (MIPS?) CPU'yu taklit etmesi gereken bir MIPS montaj programı yazıyorsunuz. Öykünümlü kayıtları sadece C ile yaptığınız gibi bir dizide saklayacağım. Muhtemelen tüm kayıtlı öykülerinizi gerçek kayıt defterlerinde tutamazsınız, çünkü programınızda başka bir şey için bazı gerçek kayıtlara ihtiyacınız olacaktır. –

cevap

0

Kendini değiştiren kod kullanmanız gerekiyor mu? Örneğin. Kayıt numarasını, çalıştırmak üzere olan bir talimata koymak? Sorun, C (var1, var2, vb.) 'De birden çok adlandırılmış değişkene sahip olma ve var değerini i değerine döndürmek zorunda kalmasıyla daha benzerdir. Üste | Geri Bildirim Ver Daha fazla bilgi Daha fazla bilgi almak için , Değer i. i bir derleme zamanı sabiti olup olmadığını önişlemcisinden ile yapabilirsiniz: (. Atlama masası, şube ağaç, ya da her neyse)

#define expandvar(x) var ## x // two step process to macro-expand x before concat 
#define var(x) expandvar(x) 
#define wantvar 4 

int foo(void) { return var(wantvar); } 
// int foo(constexpr int i) { ... } // nope 

Aksi takdirde istediğiniz gibi uygulayabilirsiniz hangi bir switch() ihtiyaç

Hepsini belleğe saklamıyorsanız ve daha sonra bu diziye bir değişken ofset kullanmıyorsanız, yazmaçlar için hiçbir dolaylı yol yoktur.

Bunu gerçekleştirmenin bir yolu, atlama adresleri tablosu yerine, hesaplanan bir atlamadır. İstediğiniz reg nerede olduğunu noktada, bu işe

move $r30, $r31 
    move $r29, $r30 
    move $r28, $r29 
    ... 
    move $r0, $r1 

atlama Bir kaydının değerini almak istiyorsa

# calculate $t0 = set_r0 + reg_num * 8. (probably using PC as the starting point, rather than actually referencing the address of set_r0) 
j $t0  # jump to one of the pairs. 

set_r0: 
    move $r0, src 
    j end 
    move $r1, src 
    j end 
    ... 

dizisi var ama diğerlerini clobber ediyorum okuyun.