Belki daha net bir örnek sağlamak için, x86_64'te -O
bayrakla derlenen
pub fn leet(a : i128) -> i128 {
a + 1337
}
derler
example::leet:
mov rdx, rsi
mov rax, rdi
add rax, 1337
adc rdx, 0
ret
(My orijinal yayın vardı u128
ziyadei128
sorduğunuzdan . İşlev her iki şekilde de aynı kodu derler, imzalı ve işaretsiz eklemenin modern bir CPU'da aynı olduğunu gösteren iyi bir gösteri.)
Diğer liste optimize edilmemiş kod üretti. Bir hata ayıklayıcıda adım atmak güvenlidir, çünkü herhangi bir yere bir kesme noktası koyabilmenizi ve programın herhangi bir satırındaki herhangi bir değişkenin durumunu inceleyebilmenizi sağlar. Okuması daha yavaş ve daha zor. Optimize edilmiş sürüm, aslında üretimde çalışacak olan koda çok daha yakındır.
a
Bu fonksiyonun parametresi bir çift 64-bit yazmaç, rsi: rdi'de geçirilir. Sonuç, başka bir kayıt çiftinde döndürülür, rdx: rax. Kodun ilk iki satırı, toplamı şu şekilde başlatır:a
.
Üçüncü satır, girişin düşük kelimesine 1337 ekler. Bu taşarsa, CPU'nun taşıma bayrağında 1'i taşır. Dördüncü satır, girişin yüksek kelimesine sıfır ekler - artı taşındıysa 1'i.
Bunu iki basamaklı bir sayıya tek basamaklı bir sayının basit bir şekilde eklenmesi olarak düşünebilirsiniz.
a b
+ 0 7
______
ancak 18,446,744,073,709,551,616 tabanında. Hala ilk önce en düşük "rakamı" ekliyorsunuz, muhtemelen bir sonraki sütuna 1 taşıyıp, ardından bir sonraki rakamı artı elde ekliyorsunuz. Çıkarma çok benzer.
Çarpma, (2⁶⁴a + b) (2⁶⁴c + d) = 2¹²⁸ac + 2⁶⁴ (ad + bc) + bd kimliğini kullanmalıdır; burada bu çarpımların her biri, bir kayıtta ürünün üst yarısını ve ürünün alt yarısını bir diğeri. Bu terimlerden bazıları atlanacak, çünkü 128'in üzerindeki bitler biru128
ve atılır. Öyle olsa bile, bu birkaç makine talimatı gerektirir. Bölünme ayrıca birkaç adım atar. İşaretli bir değer için, çarpma ve bölme işleminin ek olarak işlenenlerin işaretlerini ve sonucu dönüştürmesi gerekecektir. Bu operasyonlar hiç de verimli değil.
Diğer mimarilerde işler daha kolay veya zorlaşır. RISC-V, 128 bitlik bir komut seti uzantısını tanımlar, ancak bildiğim kadarıyla kimse onu silikonda uygulamamıştır. Bu uzantı olmadan , RISC-V mimari el kitabı bir koşullu dalı önerir :addi t0, t1, +imm; blt t0, t1, overflow
SPARC, x86'nın kontrol bayrakları gibi kontrol kodlarına sahiptir, ancak add,cc
bunları ayarlamak için özel bir talimat kullanmanız gerekir. Öte yandan MIPS, iki işaretsiz tamsayının toplamının işlenenlerden kesinlikle daha az olup olmadığını kontrol etmenizi gerektirir. Eğer öyleyse, ekleme aşıldı. En azından, koşullu dallanma olmadan taşıma bitinin değerine başka bir kayıt koyabilirsiniz.