local function print(...)
local szText = Input.GetText("Input1");
for i, v in pairs{...}do
szText = szText .. tostring(v).."\t";
end
Input.SetText("Input1", szText.."\r\n");
end;
if(not ASM.Initialize())then
error("Assembler couldn't be initialized.");
end
-- Calculate some stuff using your input!
local function asm_test_1()
local hAssembly = ASM.Assemble[[
USE32 ;-- Important, use 32 bits. Don't use USE16 and USE64, this is a 32 bit application!
ORG 100h ;-- The base
XOR EAX, EAX
MOV EAX, [ESP + 4] ;-- Place argument 1 in EAX for operation! Arguments to a function call are placed in ESP normally.
SAL EAX, 2 ;-- Shift it left 2 bits.
SUB EAX, 100 ;-- Subtract 100.
SAR EAX, 1 ;-- Shift it right 1 bit.
RETN ;-- return, the value in EAX is usually returned to the calling process.
]];
if(hAssembly.assembled)then
local result = hAssembly(120); -- Call the above block of assembly with the argument 120 in ESP
print(result);
else
local asmError = hAssembly:GetError();
if(asmError)then
if(asmError.errorCode ~= 0)then -- If it wasn't successful and errorCode is 0, then you probably tried assembling an empty block.
Dialog.Message("Assembler error: "..tostring(asmError.errorCode), "Line "..tostring(asmError.errorLine)..": "..asmError.errorMessage.."\r\nCode at line: "..asmError.errorLineString);
end
end
end
hAssembly:Free();
end
-- Call MessageBox A and proxy the arguments through assembly!
local function asm_test_2()
local user32 = Library.Load("user32.dll");
if(not user32)then return;end;
local MessageBoxA = user32:GetProcAddress_("MessageBoxA");
if(not MessageBoxA)then return;end;
local hAssembly = ASM.Assemble([[
USE32 ;-- Important, use 32 bits. Don't use USE16 and USE64, this is a 32 bit application!
ORG 100h ;-- The base
PUSH EBP ;-- Push EBP on the stack
MOV EBP, ESP ;-- Move the arguments in ESP to EBP
PUSH DWORD [EBP + 20] ;-- EBP contains the arguments, last argument at offset 20, first argument at offset 8.
PUSH DWORD [EBP + 16] ;-- PUSH pushes these values onto the stack for CALL to pass onto the called code
PUSH DWORD [EBP + 12] ;-- Push the last argument first!
PUSH DWORD [EBP + 08] ;-- So, the first PUSH rule pushes the flags (68), 2nd pushes message, 3rd pushes title, 4th pushes window handle
XOR EAX, EAX ;-- Reset the EAX register to 0
;-- Move the pointer to MessageBoxA into EAX, so we can call that function
;MOV EAX, DWORD ]]..tostring(MessageBoxA)..[[ ;-- If you use this form of concatenation, use a space after the opening operator! If you do not, newlines are ignored.
MOV EAX, DWORD [EBP + 24] ;-- Instead of concatenating the ASM, you can also provide this function with a pointer to MessageBoxA
CALL EAX ;-- Call the function address stored in EAX
POP EBP ;-- POP (remove) EBP from the stack, restoring the stack and allowing EAX to get returned.
RETN
]]);
if(hAssembly.assembled)then
-- The 68 as argument 4 below is Bitwise.Or(MB_ICONINFORMATION, MB_YESNO)
local result = hAssembly(Application.GetWndHandle(), "Hello World!", "Title", 68, MessageBoxA); -- Call the above block of assembly.
if(result == IDYES)then
print("You clicked yes! :D");
else
print("You clicked no! :(");
end
else
local asmError = hAssembly:GetError();
if(asmError)then
if(asmError.errorCode ~= 0)then -- If it wasn't successful and errorCode is 0, then you probably tried assembling an empty block.
Dialog.Message("Assembler error: "..tostring(asmError.errorCode), "Line "..tostring(asmError.errorLine)..": "..asmError.errorMessage.."\r\nCode at line: "..asmError.errorLineString);
end
end
end
hAssembly:Free();
end
-- Calculate a CRC32 checksum on data you provide!
local function CRC32(szString, initCRC)
local CRC = 0;
if(type(initCRC) == "number")then
CRC = initCRC;
end
local hAssembly = ASM.Assemble[[
USE32
ORG 100h
PUSH EBP ;-- Push EBP on the stack so it'll hold our arguments.
MOV EBP, ESP ;-- Move ESP into EBP, we use EBP to get to our arguments.
;-- Read all the arguments again and place them in registers.
MOV EDI, DWORD [EBP + 12] ;-- length
MOV ESI, DWORD [EBP + 08] ;-- pointer, the function call methods in MemoryEx obtain a pointer to the strings you provide :)
MOV ECX, DWORD [EBP + 16] ;-- init crc32
NOT ECX ;-- to mimic the behaviour of PB's CRC32Fingerprint function, we have to NOT the init crc. Usually the init crc is -1, PB works with 0. NOT 0 = -1 (0xFFFFFFFF)
MOV EDX, -1 ;-- EDX = -1
nextbyte: ;-- A label that gets the next byte from the buffer.
XOR EAX, EAX ;-- EAX = 0
XOR EBX, EBX ;-- EBX = 0
DB 0xAC ;-- LODSB instruction to get the next byte
XOR AL, CL ;-- XOR AL with CL
MOV CL, CH ;-- CL = CH
MOV CH, DL ;-- CH = DL
MOV DL, DH ;-- DL = DH
MOV DH, 8 ;-- DH = 8
nextbit: ;-- A label that gets the next bit from the byte.
SHR BX, 1 ;-- Shift the bits in BX right by 1 bit.
RCR AX, 1 ;-- (rotate through carry) Rotate bits in AX by 1
JNC nocarry ;-- Jump to nocarry if carry flag wasn't set
XOR AX, 0x08320 ;-- XOR AX with 33568
XOR BX, 0x0EDB8 ;-- XOR BX with 60856
nocarry: ;-- If the carry flag wasn't set
DEC DH ;-- DH = DH - 1
JNZ nextbit ;-- If DH isn't zero, jump to nextbit
XOR ECX, EAX ;-- XOR ECX with EAX
XOR EDX, EBX ;-- XOR EDX with EBX
DEC EDI ;-- EDI = EDI - 1, finished a byte.
JNZ nextbyte ;-- If EDI isn't zero, jump to nextbyte
NOT EDX ;-- Invert EDX bits - 1s complement
NOT ECX ;-- Invert ECX bits - 1s complement
MOV EAX, EDX ;-- Move EDX into EAX
ROL EAX, 16 ;-- Rotate bits in EAX left by 16 places
MOV AX, CX ;-- Move CX into AX
POP EBP ;-- Remove EBP from the stack, which held the arguments.
RETN ;-- Return, the value in EAX contains the CRC checksum.
]];
if(hAssembly.assembled)then
CRC = hAssembly(szString, szString:len(), CRC); -- Call the CRC code
else
local asmError = hAssembly:GetError();
if(asmError)then
if(asmError.errorCode ~= 0)then -- If it wasn't successful and errorCode is 0, then you probably tried assembling an empty block.
Dialog.Message("Assembler error: "..tostring(asmError.errorCode), "Line "..tostring(asmError.errorLine)..": "..asmError.errorMessage.."\r\nCode at line: "..asmError.errorLineString);
end
end
end
hAssembly:Free();
return CRC;
end
-- Check if your processor supports the SSE2 instruction set.
local function CPU_SSE2()
local sse2 = false;
local hAssembly = ASM.Assemble[[
USE32 ;-- Important, use 32 bits. Don't use USE16 and USE64, this is a 32 bit application!
ORG 100h ;-- The base
MOV EAX, 1h
CPUID
TEST ECX, 2000000h
JNZ @F
MOV EAX, 0
@@:
MOV EAX, 1
RETN ;-- return, the value in EAX is usually returned to the calling process.
]];
if(hAssembly.assembled)then
sse2 = (hAssembly() == 1);
else
local asmError = hAssembly:GetError();
if(asmError)then
if(asmError.errorCode ~= 0)then -- If it wasn't successful and errorCode is 0, then you probably tried assembling an empty block.
Dialog.Message("Assembler error: "..tostring(asmError.errorCode), "Line "..tostring(asmError.errorLine)..": "..asmError.errorMessage.."\r\nCode at line: "..asmError.errorLineString);
end
end
end
hAssembly:Free();
return sse2;
end
asm_test_1();
asm_test_2();
print(CPU_SSE2())
local crc = CRC32("Hello World!!");
print("CRC32 of \"Hello World!!\"", crc, "("..tostring(Bitwise.And(crc, 0xFFFFFFFF)).." unsigned)");
Comments