View Single Post
Old 09-11-2012, 06:49 PM   PM User | #1
rdspoons
New Coder

 
Join Date: Jun 2009
Posts: 81
Thanks: 0
Thanked 8 Times in 8 Posts
rdspoons is on a distinguished road
JavaScript x86 32-bit Assembler

Intel based windows 32-bit systems only.

This is a toy JavaScript assembler I wrote long, long ago.
To create and save a com file, the app needs to be run on the desktop as an HTA - just use an .hta extension instead of .htm.
The app uses VBS for binary file storage, but the assembler code and opcode data is JS.

The main points:
  • A verbose intel x86 (32-bit) Assembler made sometime around '04?
  • This is an incomplete toy 32-bit assembler. The programs it writes will not work on a 64-bit machines
  • Write x86 Assembly code in the left textarea. The compiled result displays in the right.
  • 5 small program examples are available in the selection list
  • The app creates real 32-bit com files, but the opcode results should be verified before executing any file.
  • The app is strict, inneficient, and has no built in operational help.
  • If you need to jump, you'll need to count bytes and specify the target memory locations.

Restated:
The files this code creates will only work on an intel based x86 32-bit OS.
The files will not work on modern 64-bit systems, nor on non-intel based systems.

Selected points:
The intel opcode data is held in hashes in a verbose form
Code:
//opcode elements
//a value of -1 indicates the element is not used.
//intelOpcode[N][0]=re pattern		//valid regular expression matching the opcodes mnemonic syntax
//intelOpcode[N][1]=opcodeLayout	//intel opcode binary desrciption
//intelOpcode[N][2]=RegLoc		//location of registrer in string
//intelOpcode[N][3]=ArgLoc		//location of argument in string
//intelOpcode[N][4]=ArgLen		//length of argumemt in string
//intelOpcode[N][5]=Byte Length		//length of ml instruction in bytes
//...
//CMP
//cmp reg8, imm8		1000 00x0 11111-r/m imm
//cmp al, imm		0011 1100 imm
intelOpcode["cmp byte immediate to AL"]=[]
intelOpcode["cmp byte immediate to AL"]["regexp mnemonic pattern"]=/cmp al, [0-9a-f]{2}/
intelOpcode["cmp byte immediate to AL"]["opcode bit pattern"]="00111100"
intelOpcode["cmp byte immediate to AL"]["register location in string"]=-1
intelOpcode["cmp byte immediate to AL"]["argument location in string"]=8
intelOpcode["cmp byte immediate to AL"]["argument length"]=2
intelOpcode["cmp byte immediate to AL"]["byte length"]=2

//...
The assembler function uses the opcode hash with the program input by the user to create the hex/machinelanguage code:
Code:
function Assemble(input){
	var d="00000000"
	for(var i in intelOpcode){
		if(intelOpcode[i]["regexp mnemonic pattern"].test(input.toLowerCase())==true){
			InstructionPointer+=parseInt(intelOpcode[i]["byte length"])
			d=intelOpcode[i]["opcode bit pattern"]
			if(intelOpcode[i]["register location in string"]>-1){
				var rm=regmap1[input.substr(intelOpcode[i]["register location in string"],2).toUpperCase()]
				d=d.replace(/rrr/,rm)
			}
			if(/ppp/.test(intelOpcode[i]["opcode bit pattern"])){
				var qm=regmap1[input.substr(intelOpcode[i]["argument location in string"],intelOpcode[i]["argument length"]).toUpperCase()]
				d=d.replace(/ppp/,qm)
			}
			else{
				if(i.substr(0,1)=="j"){
						d+=hextobin(input.substr(intelOpcode[i]["argument location in string"],intelOpcode[i]["argument length"]))
				}
				else{
					if(intelOpcode[i]["argument location in string"]>-1){
						if(/\[/.test(input)>0){
							var hb=input.substr(intelOpcode[i]["argument location in string"],2)
							var lb=input.substr(intelOpcode[i]["argument location in string"]+2,2)
							d+=hextobin(lb+hb)
						}
						else{
							d+=hextobin(input.substr(intelOpcode[i]["argument location in string"],intelOpcode[i]["argument length"]))
						}
					}
				}
			}
			break
		}
	}
	return d
}
Lack of document.getElementById use is due to this code targeting .hta making it mshta.exe specific.
The textarea scrolling is kept synchronized with the following code:
The id of one textarea is "instring", the other is "tres".
The n argument is 0 when tres is scrolled and 1 when instring is scrolled.
Code:
function keeptogether(n){
	if(n)
		instring.scrollTop=tres.scrollTop
	else
		tres.scrollTop=instring.scrollTop
}
The full app is in the attached zip.
Change the .txt extension to .hta to use the app.
Attached Files
File Type: zip x86_js_assembler.zip (8.5 KB, 40 views)
rdspoons is offline   Reply With Quote