Thread overview
Malloc'da Bug var sanırım.
Feb 14, 2013
kaaninel
Feb 14, 2013
kaaninel
Feb 14, 2013
kaaninel
Feb 14, 2013
kaaninel
Feb 15, 2013
Salih Dinçer
Feb 18, 2013
kaaninel
February 14, 2013

Talha Zekeriya Durmuş ile birlikte geliştirdiğimiz Rhodeus Script için yaptığım VM çalışmalarından biri fakat anlayamadığım bir sebepten dolayı EAX 0 oluyor ve EAX ı adres olarak alıp değerini okumaya çalıştığında hata veriyor. Disassembly ile bakmama rağmen EAX ı 0 yapan yani

xor EAX,EAX;

komutu sadece Malloc içinde veriliyor. Ve Disassembly de kodları gösterirken bir gariplik var ?? olarak gösteriyor bazı kusımları başta Malloc neden oluyor sandım fakat parça parça bunlar ve kodların arasında bu yüzden bunun nedenide belli değil. Büyük ihtimalle kodda birçok hata vardır hala D ye alışamadım ama koda bir el ararsanız çok iyi olur :D

module main;

import std.stdio;
import core.memory;
import std.datetime;

int main(string[] argv)
{
	int CMPt;

	OP[] App =
	[
		new OP("op_ISYS"),
		new OP("op_CMP"),
		new OP(0),
		new OP(1000000),
		new OP("op_INC"),
		new OP(2),
		new OP("op_JNE"),
		new OP(1),
		new OP("op_HLT")
	];

   void *pc;
   void*[string] Lbls;
   asm{ call l_ISYS;};Lbls["op_ISYS"] = pc + 0x4;
   asm{ call l_CMP ;};Lbls["op_CMP" ] = pc + 0x4;
   asm{ call l_INC ;};Lbls["op_INC" ] = pc + 0x4;
   asm{ call l_JNE ;};Lbls["op_JNE" ] = pc + 0x4;
   asm{ call l_HLT ;};Lbls["op_HLT" ] = pc + 0x4;


	int* point = cast(int*)GC.malloc(40);
	int* memorigin = point;

	foreach(OP v; App)
	{
		if(v.name in Lbls)
		{
			*point = cast(int)Lbls[v.name];
		}
		else
		{
			*point = v.val;
		}
		writeln(*point);
		point++;
	}

	point = memorigin;

	goto runOP;

	runOP:
		pc = cast(void*)*point;
		asm
		{
			jmp pc[EBP];
		}

	l_ISYS:
		asm{ call adresal; ret;}
		auto c1 = Clock.currTime();
		point++;
		goto runOP;

	l_CMP:
		asm{ call adresal; ret;}
		point++;
		int p1 = *point;
		point++;
		int p2 = *point;
		CMPt = p1 - p2;
		point++;
		goto runOP;

	l_INC:
		asm{ call adresal; ret;}
		point++;
		(*(memorigin+(*point)))++;
		point++;
		goto runOP;

	l_JNE:
		asm{ call adresal; ret;}
		point++;
		if(CMPt != 0) point = memorigin+(*point);
		else point++;
		goto runOP;

	l_HLT:
		asm{ call adresal; ret;}
		auto c2 = Clock.currTime();
		writeln(c2-c1);
		while(1){}
		return 0;

	adresal:
		asm
		{
			pop EBX;
			mov pc[EBP],EBX;
			ret;
		}
}

class OP
{
	int val;
	string name;

	this(int Val)
	{
		val = Val;
		name = "P";
	}

	this(string comm)
	{
		name = comm;
		val = -1;
	}
}

Kaan İNEL

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

February 14, 2013

Hoşbulduk! :D
Sorun çıkaran kısım olarak debug yaptığımda

auto c1 = Clock.currTime();

komutu neden oluyor.
Disassembly de

add byte ptr [eax],al

satırı hataya neden oluyor. Sanırım hata o anki EAX ın değerinin boş olması. Ve kodda görebileceğiniz gibi minimum düzeyde iasm kodu var. Bu sistemi tamamen iasm ile yazmıştım fakat çalışmayınca iasm kodunu yazamadığımı düşünüp d ile yazdım fakat bu halinin hata vermesi beni çok şaşırttı. Ve koddaki bütün int leri long olarak değiştirdim 64 bit olması için . Ben 32 bit üzerinde derlediğim için adreslerde 32 bit olur sanmıştım :D normalde öyle olduğunu sanıyorum. Ama yine aynı hata :S

Kaan İNEL

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

February 14, 2013

Bu kodun yaptığı tüm olay App Arrayının içindeki OP(stringlerde) label adreslerini OP(int) lerde int i malloc ile açtığım adrese sırayla yerleştirmek bu aşama fazla önemli değil şu anda önemli olan ilk runOP un çağrıldıktan sonrası . Ve açıkcası beni zorlayan hatanın d kodlarında oluşması. Her ne kadar büyük ihtimalle benim yazmış olduğum bir kod neden olsada kodları incelediğimde kendi kodlarım olmadığı için anlayamıyorum . Bu yüzden takıldım şu anda yani ben EAX a elle müdahale etmememe rağmen EAX yüzünden hata vermesi ve kaynağını bulamamam zorluyor beni .

Kaan İNEL

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

February 14, 2013

Şu an farkettim label adresleri yanlış geliyor. Sorun burda sanırım :D

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

February 14, 2013

Hşgeldin kaaninel! :)

Assembly'yi tam anladığımı söyleyemem. Gözüme çarpanlar şöyle:

void* türü int ile aynı büyüklükte olmayabilir; cast(int) yapmadan önce emin olmak gerek. Örneğin, 64 bitlik sistemlerde void* 64 bit ama int her zaman için 32 bit. (Başka dillerde int değişebilir ama D'de tam 32'dir.)

Küçük bir eniyileştirme olarak, in işleci aslında zaten verinin adresini döndürür. v.name'in tabloda iki kere aratmaya gerek yok:

       string *veri = v.name in Lbls;
       if(veri)
       {
           *point = *veri;
       }
       else
       {
           *point = v.val;
       }

Ben o gibi durumlarda üçlü işlevi seviyorum (bazıları kodu karıştırdığını düşünür):

       string *veri = v.name in Lbls;
       *point = (veri ? *veri : v.val);

Ali

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

February 14, 2013

Alıntı (kaaninel):

>

32 bit üzerinde derlediğim için adreslerde 32 bit olur sanmıştım

O zaman öyle tabii ki. :) Ben sistemi bilmediğim için normalde int ile void* arasındaki dönüşümün her zaman doğru olmayacağını belirttim.

Ali

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

February 15, 2013

Hoş geldin Kaan,

Kod çok güzel görünüyor. Yoğun bir çalışma içine girdiğim için ayrıntısıyla inceleyemiyorum ama dediğim gibi nefis görünüyor. Sorun hala devam ediyor mu; istersen adım adım ve küçük parçalar ile devam edelim.

Başarılar...

Öneri: Bu başlığı Talha'nın açtığı önceki başlık (-bknz. Inline ASM label adresi alma (http://ddili.org/forum/thread/1081)) ile birleştirsek güzel olabilir. Herhalde sorun malloc() ile ilgili değil ama adres atama ve yığın veya EAX'ın son durumu ile alakalı.

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

February 18, 2013

Özür dilerim pek giremedim hafta sonu bu yüzden görememişim. Kodu beğendiğiniz için telekkürler talhaya bir türlü beğendiremiyorum yazdıklarımı :D
Sorun şu anda anladığım kadarıyla *point olarak çağırdığımda gelen adres yanlış.

writeln(*point);

Satırından yazdırıp debugdan bu adreslere baktığımda yanlış olduğunu gördüm yani sorun çalıştırmada değil malloc la atığım bölüme adresleri atamıyor. Malloc da sorun yok sanırım ben debugda o EAX ı değiştiren en son komut Malloc görünüyordu bu yüzden hata sandım . Şu anda sanırım sadece dict e atıp okurken bir karışıklık oluyor :D


Spam olmasın buna yazayim. Şimdi farkettim sorun tamamen adres alma işleminde :D adresler yanlış geliyor


Sorun çözüldü :D Tek sorun 0x4 ekleyince çok fazla oluyormuş . ret kumutu 32 bit yani 1 adreslik yer kaplıyormuş 0x1 olarak değiştirince çalıştı .

Kaan İNEL

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

February 18, 2013

Alıntı (kaaninel):

>

Tek sorun 0x4 ekleyince çok fazla oluyormuş . ret kumutu 32 bit yani 1 adreslik yer kaplıyormuş 0x1 olarak değiştirince çalıştı.

Söylediğin doğru olmadı galiba: ret komutu tek baytlık yer kaplıyor. void* göstergesini aritmetik işlemde kullanınca değeri tek bayt adresliyormuş gibi değişir ve senin de yapmak istediğin tek adres arttırmak.

Bu da Göstergeler bölümünde yazdıklarımın yanlışı ortaya çıkartıyor:

Alıntı:

>

void* türünden olan göstergeler çok kısıtlıdırlar: Ne değerleri sonraki (veya önceki) değişkeni gösterecek biçimde değiştirilebilir [...] Bu, getirdiği esnekliğin bir sonucudur: Gösterilen asıl tür bilinmediğinden gösterilen elemanın kaç baytlık olduğu da bilinemez:

Yanlış olmuş: Doğrusu, 'void*''ın tek bayt gösteriyormuş gibi kabul edilir ve aritmetik işlemlerde değeri buna uygun olarak değişir.

Ali

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