Jump to content

An assembler, completely in AutoIt


Kip
 Share

Recommended Posts

There are 34 different versions of the MOV mnemonic. All of them use different kinds and sizes of operands.

There are 8 general purpose registers.

The MOV mnemonic takes two operands, so there are about 8*34*2 = 544 combinations.

You might think I'm forgetting the immediate values: that will decrease the amount of possibilities. Yes, but I'm not mentioning the abilities to do [eax], [eax+2] and [4*eax+ebx] either.

Anyway, I've seen people trying to convert assembly to machine code before, but they all wrote a different function for every single combination.

Not really handy, I'd say...

Right now this assembler supports the following functions:

INC

ADD

DEC

CMP

ADC

AND

OR

XOR

MOV

PUSH

JMP

XCHG

RET

SBB

SUB

POP

A hell load of Jump functions (JA, JAE, etc)

MUL

IMUL

DIV

IDIV

CALL

You could probably understand that I haven't had the time yet to test them all...

This is an example code. It should work... I hope :mellow: (It works on my 32 bit computer. I don't see why it wouldn't work on a 64 bit system)

#include "ASM.au3"
$Code = ASMInstruction("MOV","eax",10) & _      ; Move '10' to EAX
 ASMInstruction("ADD","eax",1) & _      ; Add '1' to EAX
 ASMInstruction("INC","eax") & _            ; Increase EAX (same as ADD(EAX,1) but faster)
ASMInstruction("XOR","ebx","ebx") & _   ; Shortcut for making EBX zero(0)
 ASMInstruction("MOV","bl",2) & _       ; Move '2' to BL
 ASMInstruction("ADD","eax","ebx") & _  ; Add EBX to EAX
 ASMInstruction("RET")                  ; Return EAX

$hCode = ASMCompile($Code)

$iRetVal = ASMExecute($hCode)

MsgBox(0,"sd",$iRetVal,0)

You need to download both attachments, and have to put them in the same directory.

ASM.au3

IA-32 Instruction Set.txt

Edited by Kip
Link to comment
Share on other sites

Looks clever Kip, but since I never do anything in machine code or assembler it is not something I would use or even know how to use.

I would expect that someone who does write assembler would write something like this

MOV eax 10  ; Move '10' to EAX
ADD eax 1   ; Add '1' to EAX
INC eax     ; Increase EAX (same as ADD(EAX,1) but faster)
XOR ebx ebx ; Shortcut for making EBX zero(0)
MOV bl 2    ; Move '2' to BL
ADD eax ebx ; Add EBX to EAX
RET     ; Return EAX

so wouldn't it be better if you had a text file which you imported and parsed rather than the lengthy function calls?

Since I don't know what I'm talking about just tell me if that's nonsense.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Well, I know pretty much nothing about assembly language also, but here is a very very basic parser.

#include "ASM.au3"
#include <file.au3>
Dim $lines, $code = ""
_FileReadToArray(FileOpenDialog("Select ASM Code",@DesktopDir,"All (*.*)"),$lines)

For $n = 1 to $lines[0]
    $stripComments = StringSplit($lines[$n],";")
    $split = StringSplit($stripComments[1]," ")
    For $m = 1 to $split[0]
        If $split[$m] = "" Then
            $split[0] -= 1
        EndIf
    Next
    If $split[0] <> 0 Then
        $code &= getASM($split,$split[0])
    EndIf
Next

$hCode = ASMCompile($code)
$iRetVal = ASMExecute($hCode)

MsgBox(0,"sd",$iRetVal,0)

Func getASM($codeArray,$number)
    Switch $number
        Case 1
            return ASMInstruction($codeArray[1])
        Case 2
            return ASMInstruction($codeArray[1],$codeArray[2])
        Case 3
            return ASMInstruction($codeArray[1],$codeArray[2],$codeArray[3])
    EndSwitch
EndFunc

Just put the code example of martins in a text file and then select that text file when you run my code.

Not sure if you ever have a ASMInstruction with more than three parameters, but if you do, just add it to the switch statement.

Like I said above, this is a very crude parser but it works.

Cheers,

Disabled Monkey

Edited by DisabledMonkey
Link to comment
Share on other sites

Well, I know pretty much nothing about assembly language also, but here is a very very basic parser.

#include "ASM.au3"
#include <file.au3>
Dim $lines, $code = ""
_FileReadToArray(FileOpenDialog("Select ASM Code",@DesktopDir,"All (*.*)"),$lines)

For $n = 1 to $lines[0]
    $stripComments = StringSplit($lines[$n],";")
 $split = StringSplit($stripComments[1]," ")
    For $m = 1 to $split[0]
        If $split[$m] = "" Then
            $split[0] -= 1
        EndIf
    Next
    If $split[0] <> 0 Then
        $code &= getASM($split,$split[0])
    EndIf
Next

$hCode = ASMCompile($code)
$iRetVal = ASMExecute($hCode)

MsgBox(0,"sd",$iRetVal,0)

Func getASM($codeArray,$number)
    Switch $number
        Case 1
            return ASMInstruction($codeArray[1])
        Case 2
            return ASMInstruction($codeArray[1],$codeArray[2])
        Case 3
            return ASMInstruction($codeArray[1],$codeArray[2],$codeArray[3])
    EndSwitch
EndFunc

Just put the code example of martins in a text file and then select that text file when you run my code.

Not sure if you ever have a ASMInstruction with more than three parameters, but if you do, just add it to the switch statement.

Like I said above, this is a very crude parser but it works.

Cheers,

Disabled Monkey

The maximum number of operands is 4, although I've never seen an instruction like that myself.

Besides, 2 is the maximum the assembler can handle.

Link to comment
Share on other sites

I was trying to point out that Kip's done a whole lot of great, complicated things, and tried to think of a "take it to the next level", impossible goal type of thing, and a compiler was the best I could come up with. Kinda like a "gee whiz, what'll he think of next." It was a lazy compliment, and I should have tried harder.

@trancexx, lol~

Link to comment
Share on other sites

This is great Kip. Its been awhile since I did anything in assembly, but what I remember most from when I was toying around with it was how much I hated looking up the opcodes. This will help a lot if I ever go back and try more.

Link to comment
Share on other sites

Why would you wanna look them up yourself. Can't you use an already excisting assembler to do that for you?

That's almost the same if I would ask you why would you write a new assembler when there are others out there?

And you will say because blah blah blah...

And I will say exactly. But would you understand what I said?

I wrote few bytes of instructions over a time. Never used tools for that.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Why would you wanna look them up yourself. Can't you use an already excisting assembler to do that for you?

I guess you kinda have to see it from my shoes. Back then (and still now), All I new of assembly was from the sweet ass examples trancexx was giving. I thought it was so awesome how much she was doing so much with so little cpu usage. There was alot of things done in autoit that I really didn't know how I was going to do it in an other assembler. Take this small script that just performs a sleep operation.

#include <winapi.au3>
#include <Memory.au3>

$pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
$CodeBuffer = DllStructCreate("byte[512]", $pRemoteCode)
$SleepAddress = DllCall("Kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("Kernel32.dll"), "str", "Sleep")
$SleepAddress = $SleepAddress[0]

$iMilliseconds = 5000

Local $Opcode
$Opcode &= "0x"
$Opcode &= "33DB"                                   ;xor ebx, ebx
$Opcode &= "B8" & SwapEndian($iMilliseconds)        ;move eax, $milliseconds
$Opcode &= "50"                                     ;push eax
$Opcode &= "B8" & SwapEndian($SleepAddress)         ;mov eax, $Sleep
$Opcode &= "FFD0"                                   ;call eax
$Opcode &= "53"                                     ;push ebx
$Opcode &= "58"                                     ;pop eax
$Opcode &= "C3"                                     ;ret

DllStructSetData($CodeBuffer, 1, $Opcode)

ConsoleWrite('Start Sleep...' & @CRLF)
Local $Ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), "int", 0, "int", 0, "int", 0, "int", 0)
ConsoleWrite('Done' & @CRLF)

Func SwapEndian($hex)
    Return Hex(BitOR(BitOR(BitOR(BitShift($hex, 24), _
            BitAND(BitShift($hex, -8), 0x00FF0000)), _
            BitAND(BitShift($hex, 8), 0x0000FF00)), _
            BitShift($hex, -24)), 8)
EndFunc;==>SwapEndian

How do I do the dllcalls to get the function address? How do I do the SwapEndian function? What the fuck is the SwapEndian function? :mellow:

I'm sure there were ways, but for what I was doing and what I new of assembly, to me it was just easier.

Link to comment
Share on other sites

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

Func SwapEndian3($iVal)
    Return Hex(Int(Binary('0x' & Hex($iVal)) & Binary(0)))
EndFunc
Is ~60% faster than original SwapEndian() in above post. (less mystifying code to) :(

I kinda think the speed of the swapendian function is really trivial. Its the execution of the opcode that really matters. Also that part was eventually changed to
Func SwapEndian($iValue)
    Return Hex(BinaryMid($iValue, 1, 4))
EndFunc   ;==>SwapEndian

$val = 2365100092 {I6} (0x8C.F8.90.3C)
$ORG = FFFFFF8C {St}
$SE3 = 3C90F88C {St}
$val = -254955044 {I6} (0xFF.FF.FF.FF.F0.CD.B1.DC)
$ORG = FFFFFFF0 {St}
$SE3 = DCB1CDF0 {St}
I have no clue what that means. :mellow:
Link to comment
Share on other sites

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

Maybe this ASM interpreter can be useful. I'm using it to verify ASM code result.

#include <GUIConstants.au3>
#include "ASM.au3"
Global $ASMCode = ""

$ASMCode &= "MOV eax 10" & @CrLf
$ASMCode &= "ADD eax 1" & @CrLf
$ASMCode &= "INC eax" & @CrLf
$ASMCode &= "XOR ebx ebx" & @CrLf
$ASMCode &= "MOV bl 2" & @CrLf
$ASMCode &= "ADD eax ebx" & @CrLf
$ASMCode &= "RET"

Global $Source, $Result

$hWnd = GUICreate("ASM Console", 400, 480)
;--------------------------------------------------
$LabelTarget = GUICtrlCreateLabel("Your ASM:", 10, 10, 380, 21)
$Source = GUICtrlCreateEdit($ASMCode, 10, 40, 380, 150)
$Result = GUICtrlCreateEdit('', 10, 200, 380, 230)
;--------------------------------------------------
$Execute = GUICtrlCreateButton("Execute", 150, 440, 100, 21)
GUISetState()

; Start the main loop
While 1
$Msg = GUIGetMsg()
Select
Case $Msg = $GUI_EVENT_CLOSE
 Exit
Case $Msg = $Execute
  RunASM()
EndSelect
WEnd

;===============================
func RunASM()
local $SourceContent, $ResultContent, $cmpCode
 $SourceContent = GUICtrlRead($Source)
 $ASMLines = StringSplit(StringStripCR ($SourceContent),@Lf)
 $Code = ""
 for $i = 1 to $ASMLines[0]
  $ASM = StringSplit($ASMLines[$i]," ")
  Switch $ASM[0]
  case 1
    $Code &= ASMInstruction($ASM[1])
  case 2
    $Code &= ASMInstruction($ASM[1],$ASM[2]) 
  case 3
    $Code &= ASMInstruction($ASM[1],$ASM[2],$ASM[3]) 
  case 4
    $Code &= ASMInstruction($ASM[1],$ASM[2],$ASM[3],$ASM[4]) 
  EndSwitch
 next
 $cmpCode = ASMCompile($Code)
 $ResultContent = ASMExecute($cmpCode)
 GUICtrlSetData($Result, $ResultContent)
endfunc

The point of world view

Link to comment
Share on other sites

Maybe this ASM interpreter can be useful. I'm using it to verify ASM code result.

#include <GUIConstants.au3>
#include "ASM.au3"
Global $ASMCode = ""

$ASMCode &= "MOV eax 10" & @CrLf
$ASMCode &= "ADD eax 1" & @CrLf
$ASMCode &= "INC eax" & @CrLf
$ASMCode &= "XOR ebx ebx" & @CrLf
$ASMCode &= "MOV bl 2" & @CrLf
$ASMCode &= "ADD eax ebx" & @CrLf
$ASMCode &= "RET"

Global $Source, $Result

$hWnd = GUICreate("ASM Console", 400, 480)
;--------------------------------------------------
$LabelTarget = GUICtrlCreateLabel("Your ASM:", 10, 10, 380, 21)
$Source = GUICtrlCreateEdit($ASMCode, 10, 40, 380, 150)
$Result = GUICtrlCreateEdit('', 10, 200, 380, 230)
;--------------------------------------------------
$Execute = GUICtrlCreateButton("Execute", 150, 440, 100, 21)
GUISetState()

; Start the main loop
While 1
$Msg = GUIGetMsg()
Select
Case $Msg = $GUI_EVENT_CLOSE
 Exit
Case $Msg = $Execute
 RunASM()
EndSelect
WEnd

;===============================
func RunASM()
local $SourceContent, $ResultContent, $cmpCode
 $SourceContent = GUICtrlRead($Source)
 $ASMLines = StringSplit(StringStripCR ($SourceContent),@Lf)
 $Code = ""
 for $i = 1 to $ASMLines[0]
 $ASM = StringSplit($ASMLines[$i]," ")
 Switch $ASM[0]
 case 1
 $Code &= ASMInstruction($ASM[1])
 case 2
 $Code &= ASMInstruction($ASM[1],$ASM[2]) 
 case 3
 $Code &= ASMInstruction($ASM[1],$ASM[2],$ASM[3]) 
 case 4
 $Code &= ASMInstruction($ASM[1],$ASM[2],$ASM[3],$ASM[4]) 
 EndSwitch
 next
 $cmpCode = ASMCompile($Code)
 $ResultContent = ASMExecute($cmpCode)
 GUICtrlSetData($Result, $ResultContent)
endfunc

People, the fourth parameter of the ASMInstruction() function can't be used for third operands at all. I don't know where you got that idea.:mellow:

It is for specifying the size of pointers and/or the data they point to.

For example:

PUSH [myLabel];

There is no way to tell the size of the data 'myLabel' is pointing to, so that's why the $iSize parameter is there for:

PUSH dword [myLabel];

Edited by Kip
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...