Forum: D Programlama Dili RSS
Inline ASM label adresi alma
Avatar
zekeriyadurmus #1
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Inline ASM label adresi alma
Biraz kafa dinleyip label adresi almaya tekrar bakınca sonunda adres alma işlemini yaptım :)

Yapmışken sizinle de paylaşayım dedim :)

Ama burada adresleri aldıktan sonra
opcodes[i]
  yi bir değişkene eşitleyip altta bir asm kodu olarak call yapıyorum. Burdaki gereksiz kodları silip sadece asm kodu olmasını yapamadım bir türlü.

Ve bir soru soracağım şimdi ben burada call pc yapıyorum ama call pc yapmak yerine jmp pc şeklinde bir kullanım yapsam daha hızlı olur mu?

Sanki burada call kullanımı sistemi yavaşlatıyor gibi geldi

module main;
 
import std.stdio;
 
void main(){
 
    void *pc;
    void*[] opcodes;
    //Labelleri diziye atalım :)
    asm{ call op_inc;};pc += 0x4;opcodes ~= pc;
    asm{ call op_var;};pc += 0x4;opcodes ~= pc;
    asm{ call op_cmp;};pc += 0x4;opcodes ~= pc;
    asm{ call op_jne;};pc += 0x4;opcodes ~= pc;
    asm{ call op_hlt;};pc += 0x4;opcodes ~= pc;
 
    for(int i=0; i<opcodes.length; i++){
        pc = opcodes[i];
        asm { call pc;}
    }
    writeln("işlemler tamam");
    while(1){}
    return;
 
 
 
    /*
        Labeller
    */
    op_inc:
        asm{
            call adresal;
            mov pc[EBP], EAX;
            ret;
        }
        writeln("inc");
        asm{ret;}
    op_var:
        asm{
            call adresal;
            mov pc[EBP], EAX;
            ret;
        }
        writeln("var");
        asm{ ret;}
    op_cmp:
        asm{
            call adresal;
            mov pc[EBP], EAX;
            ret;
        }
        writeln("cmp");
        asm{ret;}
    op_jne:
        asm{
            call adresal;
            mov pc[EBP], EAX;
            ret;
        }
        writeln("jne");
        asm{ ret;}
    op_hlt:
        asm{
            call adresal;
            mov pc[EBP], EAX;
            ret;
        }
        writeln("hlt");
        asm{ ret;}
    //Adres almak için
    asm{adresal: pop EBX ; mov EAX,EBX; push EBX; ret;}
}

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
zekeriyadurmus:
call pc yapmak yerine jmp pc şeklinde bir kullanım yapsam daha hızlı olur mu?

Ben bilmiyorum; denenebilir... Ama call işlev gibi çağrılınca geri gelen bir şey değil mi? jmp ise oraya atlıyor ama bir daha geri dönmüyor, değil mi? O farklarının üstesinden gelinirse belki jmp daha hızlıdır. (?)

Ali
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Kodu biraz kısalttım çünkü bu sefer stack'den çektiğimiz adresi geri koymaya gerek yok. Böylece ret gördüğü yerde elde edilen adresi işaretçi diziye ekleyecek ve sonra bir diğerine geçecek. İşte bu yüzden adresi 4 birim ötelemeye de gerek kalmadı. Böylesi daha hızlı olsa gerek...:)

import std.stdio;
 
void main(){
 
    void *pc;
    void*[] opcodes;
    //Labelleri diziye atalım :)
    asm{ call op_inc;};opcodes ~= pc;
    asm{ call op_var;};opcodes ~= pc;
    asm{ call op_cmp;};opcodes ~= pc;
    asm{ call op_jne;};opcodes ~= pc;
    asm{ call op_hlt;};opcodes ~= pc;
 
    foreach (opc; opcodes) asm {
        call opc;
    }
    
    writeln("işlemler tamam");
    return;
 
    /*
       Labeller
    */
 
    op_inc: asm{ call adresal; }
        writeln("inc");
        asm{ ret; }
        
    op_var: asm{ call adresal; }
        writeln("var");
        asm{ ret; }
        
    op_cmp: asm{ call adresal; }
        writeln("cmp");
        asm{ ret; }
        
    op_jne: asm{ call adresal; }
        writeln("jne");
        asm{ ret; }
        
    op_hlt: asm{ call adresal; }
        writeln("hlt");
        asm{ ret; }
        
    //Adres almak için
    adresal: asm{
        pop EBX;
        mov pc[EBP],EBX;
        ret;
    }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
kaaninel #4
Üye Ock 2013 tarihinden beri · 22 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
    op_inc: asm{ call adresal; }
        writeln("inc");
        asm{ ret; }
yapmak yerine
 
    op_inc: asm{ call adresal; ret;}
        writeln("inc");
yapmak daha mantıklı gibi :D

Kaan İNEL
Avatar
zekeriyadurmus #5
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
ASM öğrenmeye başlamama sebep olan D'nin olmayan bir özelliği artık gelecek D sürümüyle beraber gelecek :)

İlgili commit aşağıdadır.

https://github.com/D-Programming-Language/dmd/commit/c94f8…

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Süper! Sen ve başkaları bu eksiklikten çok çekmiştiniz. :)

Ali
Avatar
zekeriyadurmus #7
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Çok eski bir konuyu hortlatmış oluyorum ama belki birilerinin ihtiyacı olabilir.

Şu an mevcut D de label adresi ile alakalı ufak bir gelişme var.

import std.stdio;
 
void main(){
  asm{
    mov EAX, label; // Bu labelin adresini almak yerine adrese erişip değerini okuyor.
    //Bu durumda labelin bulunduğu adresten itibaren 4 baytlık makine kodunu EAX'a yükleyecek.
    push label; // Adresi stack'a atıyoruz.
    pop label; // Adresi stackden çekiyoruz ve artık EAX adresi barındırıyor.
    jmp EAX; // Ekrana Merhaba yazacak olan satıra atlar.
  }
  return;
  label:
  writeln("Merhaba");
}

Eskisine nazaran biraz daha kolaylaştı fakat hala olması gereken bu değil. Bana kalırsa push, pop a gerek kalmadan ilk baştaki gibi mov yapabilmek yeterli olmalı.

Gerekli midir bilmem ama http://ddili.org/ders/d/etiketler.html kısmına eklenebilir belki.

Zekeriya
Bilgi meraktan gelir...
Bu mesaj zekeriyadurmus tarafından değiştirildi; zaman: 2015-10-28, 08:57.
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Peki mov EAX, label; yapmanın etkisi ne o zaman? push ve pop'a ihtiyaç olduğundan emin misin?

(Bu, etiketler bölümü için fazla ileri bir konu. Zaten assembly kitapta bütünüyle gözardı ediliyor.)

Ali
Avatar
zekeriyadurmus #9
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
mov EAX, label;

aslında aşağıdaki gibi bir hal alıyor.

mov EAX, dword ptr [label];

Yani adrese erişip veri okuyor. Push,pop ve mov kodlarını deneyebilirsiniz Ali hocam.

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #10
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bende şu da çalıştı ama galiba EAX olduğu için -m32 ile derlemek gerekiyor:
import std.stdio;
 
void main(){
  asm{
    push label; // Adresi stack'a atıyoruz.
    pop EAX; // Adresi stackden çekiyoruz ve artık EAX adresi barındırıyor.
    jmp EAX; // Ekrana Merhaba yazacak olan satıra atlar.
  }
  return;
  label:
  writeln("Merhaba");
}
Ali
Avatar
zekeriyadurmus #11
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
import std.stdio;
 
void main(){
  asm{
    mov EAX, label; // Bu labelin adresini almak yerine adrese erişip değerini okuyor.
    jmp EAX; // Ekrana Merhaba yazacak olan satıra atlar.
  }
  return;
  label:
  writeln("Merhaba");
}

Sorun bu kodun çalışmaması :) Bana kalırsa bu özelliğin de eklenmesi gerekiyor.

Zekeriya
Bilgi meraktan gelir...
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-19, 04:23:14 (UTC -08:00)