Jump to page: 1 2
Thread overview
January 06, 2013

Merhaba inline asm ile uğraşıyorum ama normalde c de çalışan aşağıdaki kod d de çalışmıyor. Aslında bunun gibi çok örnek var çalışmayan acaba d nin inline asm si c nin inline asm sinden farklı mı?

module dx;
import std.stdio;

int main(){
label:
	void* p;
   asm{ mov [p],offsetof label;}
	return 0;
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 06, 2013

Bakacam birazdan ama D'de bu olaylar biraz daha farklı...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 06, 2013

Teşekkürler hocam, o sayfanın başında cevap varmış...:)

void *pc;
asm {
 call L1 ;
 L1: ;
 pop EBX ;
 mov pc[EBP],EBX ; // pc now points to code at L1
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 06, 2013

Bunun nedenlerinin başında C'de ve C++'ta asm komutlarının standart olmaması gelir. O dillerde her derleyici kendi komutlarını tanımlayabilir ve yalnızca onları tanıyabilir. D'de ise standarttır.

Aradığın herşey herhalde şuradadır:

http://dlang.org/iasm.html

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 08, 2013

Şu kodu deneme fırsatı buldum. Gayet hoşmuş...:)

import std.stdio;

void main() {
 void *pc; // program counter
 bool st;  // store flag

 L1a:
   "L1a: ".writeln(pc);
   if(!pc) asm {
      pop EBX ; mov pc[EBP], EBX ;
   } // pc now points to code at L1a ;
   "L1a: ".writeln(pc);

 pc = null;

 L1b:
   "L1b: ".writeln(pc);
   if(!pc) asm {
      pop EBX ; mov pc[EBP], EBX ;
   } // pc now points to code at L1b ;
   "L1b: ".writeln(pc);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 08, 2013

Salih hocam örneğiniz için teşekkür ederim. Kusura bakmayın bilgisayarın sorunlarıyla uğraşmaktan ancak bakmak için fırsat bulabildim.

Sizden bir şey rica etsem yapabilir misiniz?

import std.stdio;

void main() {
	void *pc; // program counter
	bool st;  // store flag

	asm{
		call Komut1;
		//Adrese ret den sonraki yeri geçecek kadar değer arttırma.
		mov pc[EBP], EAX;
		//pc adresini çağırma
	}
	writeln(pc);
	return;

Komut1:
	asm {
		mov EAX, EBX;
		ret;
   }
   "Komut1".writeln();
   return;
Komut2:
	asm {
		mov EAX, EBX;
		ret;
   }
   "Komut2".writeln();
   return;
}

Yorum satırlarının olduğu yerlere gerekli işlemi yapabilecek kodu açıklayarak yazabilir misiniz?

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 09, 2013

Bence adım adım gidelim çünkü tam olarak ne yapmak istediğini anlayamadım. Yoksa bir şeyi arttırmak veya yığından veri çekmek sorun değil. Ama yığınla çalışırken onun kurallarına göre hareket etmemiz gerekiyor.

Nedir bunlar?

  • Yığından POP ile veri çekeriz, PUSH ile de veriyi önceki üzerine yığarız.
  • Bu işlemler olurken ESP (Stack Pointer) değeri artar/azalır...
  • Veriler tersine yazıldığı için POP sırasında artar, PUSH sırasında azalır!
  • Aynı şekilde CALL ve RET komutları da gizli bir şekilde yığını kullanır.

Öyleyse biz CALL ile çağırdığımız altyordamın adresini POP ile okuyabiliriz. Ancak dikkat; eğer tekrar PUSH kullanmazsak işler karışacaktır! Çünkü yığıttan veri eksilmiş (SP artmış...) ve doğru olmayan bir adrese dönmemize sebep olmuştur. Hatta dönmeden yazılım RET'i gördüğü yerde sonlanabilir.

Yukarıdaki kodu düzenlememiz gerekiyor çünkü EBX'den herhangi bir veriyi ekrana yazdırıyoruz:

:   :   :
   void *pc; // program counter
   asm{
       call Komut1;
       mov pc[EBP], EAX;
   }
   writeln(pc);
   return;

Komut1:
   asm {
       pop EBX;
       mov EAX, EBX;
       push EBX;
       ret;
   }
:   :   :

Şimdi sonraki adıma geçelim ve EAX'daki veriyi neden arttırmak istediğini öğrenerek devam edelim...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 09, 2013

Öncelikle tekrar teşekkür ederim. Eaxdaki veriyi arttırmak istememin sebebi şu ret den sonra labele ait kodlar olacak benim aslında adresini almak istediğim yer o komutların başlangıç yeri. Bunu da O labelin adresini ret komutuna kadar arttırmak ve ret komutundan sonraki kodların o adresi çağırınca çalışmasını sağlamak.

Bir dizi olacak örneğin

auto dizi = ["komut1": adress1, "komut2": "adress2"];

şeklinde adresini bulduğumuz bütün verileri bu diziye atacağız.

Ve bu adresi call ile nasıl çağıracağız

call pc şeklinde olmuyor.

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 10, 2013

Şimdi anladım; o yüzden Komut1 ve Komut2 altyordamlarına sahip örnekte hiç bir zaman uğranılamayacak bölümler var. Herhalde belirttiğin gibi maksat, bu bölümlere dilediğimizde atlamak.

Bakalım bunu yapabilecek miyiz!

Eğer olmuyorsa, bütünlüğü korumak için bir kısıtlama konulmuştur. Belki yabancı forumda işin uzmanlarına danışmamız gerekebilir. Ben bir kaç deneme yapayım birazdan sonuçları aktarırım...


Evet, pc yerine done yazdığımızda sorunsuz bir şekilde istediğimiz altyordama atlıyor. Ancak adresini aldığımız "subroutine" etiketine geri dönemiyoruz. Dönsek' if()''den dolayı 'asm{}' bloğunu atlayıp "done" etiketine düşmesi gerekiyordu. Bunun sebebi; sanırım, ister köşeli isterseniz doğrudan 'jmp pc' yazalım, bizi değişkenin tanımlandığı adrese götürmesi. Koda bakar mısınız; yanılıyor muyum?

import std.stdio;

void main() {
 void * pc;

 asm{
   call subroutine    ; // Branching...
   mov  pc[EBP], EAX  ; // Source of copy to [pc]
   // Jumping:
   //jmp  pc            ; /*
   jmp  [pc]          ; /***  jmp	dword ptr -4[EBP] ***/
 }

 subroutine:
   if(!pc) asm {
     pop  EBX      ; // Load saved state,
     mov  EAX, EBX ; // from current stack...
     push EBX      ; // Save previous stack state
     ret           ; // Return...
   }

 done:
   "done: ".writeln(pc);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 10, 2013

Evet kesinlikle öyle.

http://d.puremagic.com/issues/show_bug.cgi?id=8448 bu adreste "add EAX, 4" şeklinde adrese 4 ekleyerek ret den sonraki kısmın adresine gitmiş.

Belki bu şekilde adresi arttırarak yapılabilir.

Veya push ile adresi geri yerine koyduktan sonra cmp ile pc değişkenine değer yazılıp yazılmadığına bakarız eğer yazılmışsa je ile ret den sonra tanımladığımız labele atlayabiliriz

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2