EnglishРусский  

   ..

   compl.g

   lexasm.g

   lexasm.lex

   main.g

   readme.txt

   test.asm

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2006, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project <http://www.gentee.com>. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * compl.g 02.11.06
 11 *
 12 * Author: Sergey Kurganov ( pretorian ) 
 13 *
 14 * Description: Example of the using assembler compiler for gentee     
 15 *
 16 ******************************************************************************
 17 *Commands:	NOP, CLC, CLD, CLI, LAHF, SAHF, STC, STD, STI,
 18 *				INC reg32, DEC reg32, PUSH reg32/num32, pop reg32
 19 *           MUL reg32, DIV reg32, NEG reg32, NOT reg32
 20 *
 21 *Register(reg32):	eax,ebx,ecx,edx,esp,ebp,esi,edi
 22 ******************************************************************************/
 23 include
 24 {
 25    $"..\..\lib\lex\lex.g"
 26    "lexasm.g"
 27 }
 28 
 29 type opcode
 30 //опкод
 31 {
 32 	uint	len	//длина опкода
 33 	byte	op1	//первый опкод
 34 	byte	op2	//второй опкод
 35 	byte	op3	//третий опкод
 36 	byte	op4	//четвертый опкод
 37 	byte	op5	//пятый опкод
 38 }
 39 
 40 method opcode.clear()
 41 //очистить опкод
 42 { this.len=0 }
 43 
 44 method opcode.print()
 45 //вывести на консоль опкод
 46 {
 47 	str i
 48 	if this.len>0:i = hex2stru( i, this.op1 )+" "
 49 	if this.len>1:i = hex2stru( i, this.op2 )+" "
 50 	if this.len>2:i = hex2stru( i, this.op3 )+" "
 51 	if this.len>3:i = hex2stru( i, this.op4 )+" "
 52 	if this.len>4:i = hex2stru( i, this.op5 )+" "
 53 
 54 	print( "\t" + i + "\n" )
 55 }
 56 
 57 method opcode.save(uint opcod)
 58 //записать следующий опкод
 59 {
 60 	this.len++
 61 	switch this.len
 62 	{
 63 	 case 1 : this.op1=byte(opcod)
 64 	 case 2 : this.op2=byte(opcod)
 65 	 case 3 : this.op3=byte(opcod)
 66 	 case 4 : this.op4=byte(opcod)
 67 	 case 5 : this.op5=byte(opcod)
 68 	}
 69 }
 70 
 71 method opcode.save32(uint opcod)
 72 //Запись 32-битного числа в опкод
 73 {
 74 	this.save( byte(opcod & 0xff))
 75 	this.save( byte(( opcod & 0xff00 ) >> 8 ))
 76 	this.save( byte(( opcod & 0xff0000 ) >> 16 ))
 77 	this.save( byte(( opcod & 0xff000000 ) >> 24 ))
 78 }
 79 
 80 method uint uint.arrfindtrue(arr myarr)
 81 	//поиск в массиве числа uint
 82 	{
 83 	foreach i,myarr: if i==this: return 1
 84 	return 0
 85 	}
 86 	
 87 func main<main>
 88 {
 89    str     in, stemp
 90    uint    lex, i, off, tempop
 91    arrout  out
 92 	opcode	code
 93 	arr op1 = %{0xC0, 0xC5, 0xC9, 0xC7, 0xC4, 0xC3, 0xC6, 0xCA, 0xC8}
 94 	arr op2 = %{0x8C, 0x88, 0xB3, 0xAD, 0x8D, 0x89, 0x9B, 0x9A}
 95 
 96 	subfunc printitem(lexitem li)
 97 	//выводит на консоль расшифровку элемента лексики (для отладки)
 98 	{
 99 	   print("type=\( hex2stru("", li.ltype )) pos = \(li.pos) len=\(li.len ) 0x\(hex2stru("", li.value )) \n")
100 	}
101 
102 	subfunc printcommand(lexitem li)
103 	//выводит на консоль команду ассемблера (для отладки)
104 	{
105 		stemp.substr( in, li.pos, li.len )
106 		print( " "+= stemp + " " )
107 	}
108 	
109 	subfunc command(lexitem li)
110 	//проверяет является ли элемент коммандой
111 	{
112 		if li.ltype != $ASM_NAME || li.value < 0x40
113 		{
114 			print("Wrong command ")
115 			getch()
116 			exit(1)
117 		}
118 	}
119 	
120 	subfunc lexitem nextli()
121 	//перейти на следующий элемент
122    {
123       off += sizeof( lexitem )
124       i++
125       return off->lexitem
126    }
127 	 
128 	subfunc uint register32(uint ltype value)
129 	//Возращает добавочное число к опкоду для 32 битных регистров
130 	{
131 		if ltype != 0x50000 || value < 0x10 || value > 0x17
132 		{
133 			print("Wrong command ")
134 			getch()
135 			exit(1)
136 		}
137 	return value & 0b111 	
138 	}
139 
140 	out.isize = sizeof( lexitem )
141    in.read( "test.asm" )	//Текст программы
142    lex = lex_init( 0, lexgasm.ptr())
143 	gentee_lex( in->buf, lex, out )
144    off = out.data.ptr()	//начальный адрес разобранного текста
145 
146 		//Разбор асм кода
147    fornum i, *out
148    {
149       uint  li 
150       li as off->lexitem	//берем один элемент из разобранного текста
151 		// ltype - тип элемента
152 		// pos - позиция в тексте
153 		// len - длина элемента
154 		// value - значение элемента
155       if li.ltype == $ASM_LINE : off += sizeof( lexitem ); continue 
156       //printitem(li)
157 		command(li)
158 		printcommand(li)
159 			
160 		if li.value.arrfindtrue(op1)
161 			{
162 			//Команды без операндов
163 			switch li.value
164 				{
165 				case 0xC0 : code.save(0x90) //NOP
166 				case 0xC5 : code.save(0xF8) //CLC
167 				case 0xC9 : code.save(0xFC) //CLD			
168 				case 0xC7 : code.save(0xFA) //CLI
169 				case 0xC4 : code.save(0x9F) //LAHF
170 				case 0xC3 : code.save(0x9E) //SAHF
171 				case 0xC6 : code.save(0xF9) //STC
172 				case 0xCA : code.save(0xFD) //STD
173 				case 0xC8 : code.save(0xFB) //STI
174 				}
175 			}
176 		if li.value.arrfindtrue(op2)
177 			{
178 			//Команды с одним операндом (регистром 32 бита)
179 			tempop=li.value
180 			li as nextli()
181 			printcommand(li)
182 			switch tempop
183 				{
184 				case 0x8C : code.save(0x40 + register32(li.ltype, li.value)) //INC
185 				case 0x88 : code.save(0x48 + register32(li.ltype, li.value)) //DEC
186 				case 0xB3 //PUSH
187 					{
188 					if li.ltype == $ASM_NUMBER
189 						{
190 						code.save(0x68)
191 						code.save32(uint(stemp.substr(in,li.pos,li.len)))
192 						}
193 					else : code.save(0x50 + register32(li.ltype, li.value))
194 					}							
195 				case 0xAD : code.save(0x58 + register32(li.ltype, li.value))//POP
196 				case 0x8D //MUL
197 					{
198 					code.save(0xF7)
199 					code.save(0xE0 + register32(li.ltype, li.value))
200 					}
201 				case 0x89 //DIV
202 					{
203 					code.save(0xF7)
204 					code.save(0xF0 + register32(li.ltype, li.value))
205 					}
206 				case 0x9B //NEG
207 					{
208 					code.save(0xF7)
209 					code.save(0xD8 + register32(li.ltype, li.value))
210 					}
211 				case 0x9A //NOT
212 					{
213 					code.save(0xF7)
214 					code.save(0xD0 + register32(li.ltype, li.value))
215 					}
216 				}
217 			}
218 		code.print()
219 		code.clear()
220 		off += sizeof( lexitem )
221 		
222 		//Здесь будет код для записи опкода в буфер
223 		
224    }
225 	lex_delete( lex ) 
226    congetch("Press any key...")
227 }
228 
Редактировать