2017-10-15 52 views
6

Bir araç tarafından oluşturulan x86_64 mimarisi için bazı gnu assembler koduna sahip ve bu talimatları vardır:callq komutu nedir?

movq %rsp, %rbp 
leaq str(%rip), %rdi 
callq puts 
movl $0, %eax 

ben "callq" talimatı üzerine fiili belgelerine bulamıyor.

I http://support.amd.com/TechDocs/24594.pdf baktım "AMD64 Mimarisi Programcı Kılavuzu Cilt 3: Genel Amaçlı ve Sistem Talimatları" ama onlar sadece yakın ÇAĞRI ve uzak talimatları açıklar.

gnu assembler https://sourceware.org/binutils/docs/as/index.html belgelerine baktım ama desteklediği yönergeleri detaylandıran bölümü bulamadım.

Bunun bir işlev çağrısını anlıyorum, ancak ayrıntıları bilmek istiyorum. Onları nerede bulabilirim?

+0

Ben, bu kadar sık ​​yorumların yerine cevaplar olarak cevaplarınızı sonrası neden @Peter, merak ediyorum. – prl

+1

@prl: Ben dendiğinde muhtemelen çiftleri olduğunu, ancak ben bir dup hedefe bakmak için zaman almadı. Bunun için bir bakacağım; Bir kopyası değilse, gerçek bir cevap yazmaya değer. Ve haklısın, bunu bir cevap olarak gönderebilirdim. –

+2

@prl: Özellikle 'callq' ile ilgili mevcut bir soru bulamadım. Ve dalları ve diğer yığın yönergeleri için varsayılan işlenen boyutlar hakkında söylenecek açık olmayan şeyler var. Bu bir acemi sorusu, ama aslında bir değişiklik için cevap vermeye değer bir şey, eğer tüm kötü ile huysuz olmayı bıraksam "kodum işe yaramaz ve hiçbir şey bilmiyorum" sorular. –

cevap

7

Sadece call numaralı telefondan. Intel/AMD kılavuzlarında talimatlara bakmak istiyorsanız Intel-sözdizimi demontajını kullanın.

q işlenen büyüklüğü soneki teknik olarak geçerli (64 bitlik bir geri dönüş adresi gönderir ve RIP'i 64 bitlik bir kayıt defteri olarak kabul eder), ancak komut önekleriyle geçersiz kılmanın bir yolu yoktur. Yani, calll ve callw, 64 bit modunda kodlanamaz, bu nedenle sadece bazı AT & T sözdizimi araçlarının call yerine callq olarak gösterdiği rahatsızlıktır. Bu elbette retq için de geçerlidir.

32 ve 64 bit modlarında farklı araçlar farklıdır. (Godbolt)

  • gcc -S: her call/ret. Güzel.
  • clang -S: callq/retq ve calll/retl. En azından sürekli olarak sinir bozucu.
  • objdump -d: callq/ retq (açık 64 bit) ve call/ ret (32-bit örtük). Tutarsız ve biraz aptaldır çünkü 64-bit'in işlenen büyüklükte bir seçimi yoktur, ancak 32-bit yapar. (Gerçi değil yararlı seçim. callw 16 bite VAP truncates) diğer taraftan rağmen

    , 64 bit modunda en talimatlar için (bir REX.W öneki olmadan) varsayılan işlenen boyutu hala 32'dir. Ancak add $1, (%rdi), işlenen büyüklükte bir sonek gerektirir; Hiçbir şey ima etmiyorsa, assembler sizin için 32 bit almaz. OTOH, push, pushw $1 ve pushq $1 her ikisi de 64 bit modda kodlanmış (and usable in practice) olsa bile, örtülü olarak pushq'dur.

(yukarıda bağlantısı) Intel'in talimat-set ref kılavuzda itibaren

: yakın bir çağrı mutlak İçin

, genel amaçlı kayıt veya bir hafıza konumda dolaylı belirtilen ofset mutlak (r/m16, r/m32 veya r/m64). İşlenen büyüklük özniteliği, hedef işlenenin boyutunu belirler (16, 32 veya 64 bit).64 bit modunda, yakın çağrı için işlenen boyutu (ve tüm yakın dallar) 64-bit zorlanır zaman.

rel32 için ... mutlak uzaklıklar gibi, işlenen boyutlu özelliği, hedef işlenen (16, 32, ya da 64 bit) boyutunu belirler. işlenen boyutu yakın şubeleri için 64 bit zorlanır çünkü 64 bit modunda hedef işlenen her zaman 64-bit olacak.

32-bit modunda, 16 bit ya da bir mutlak 16 bit adres kullanan bir call r/m16 için VAP keser bir 16-bit call rel16 kodlayabilir. Ancak el kitabının da belirttiği gibi, işlenen boyut 64-bit kipte sabitlenmiştir.

+1

"Sürekli olarak can sıkıcı" formunu beğeniyorum.