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)");