EnglishРусский  

   ..

   compl.g

   lexasm.g

   lexasm.lex

   main.g

   readme.txt

   test.asm

Ads

Perfect Automation tool
All-In-One: Script editor, Launcher, Scheduler, Keyboard & Mouse Recorder. Try now!

CreateInstall
Freeware and commercial installers.

Cell Phone Batteries
Batteries Plus offers batteries for laptop, camcorder, cell phone, camera.

Gentee needs your help!
How to advertise with us
 
laptop battery

  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 }
Edit