Machine code: Difference between revisions

Added S-BASIC example
(Added S-BASIC example)
 
(47 intermediate revisions by 18 users not shown)
Line 1:
{{task}}
The task requires poking machine code directly into memory and executing it. The machine code is the architecture-specific opcodes which have the simple task of adding two unsigned bytes together and making the result available to the high-level language.
 
ThisFor example, the following assembly language program is strictlygiven for x86 (32 bit) architectures. :
 
<syntaxhighlight lang="asm">mov EAX, [ESP+4]
The machine code is the opcodes of the following simple program:
 
<lang asm>mov EAX, [ESP+4]
add EAX, [ESP+8]
ret</langsyntaxhighlight>
 
whichThis translateswould translate into the following opcodesopcode bytes:
(<syntaxhighlight lang="text">139 68 36 4 3 68 36 8 195)</syntaxhighlight>
and in Hex this would correspond to the following:
("8B" "44" "24" "4" "3" "44" "24" "8" "C3")
 
Or in hexadecimal:
<syntaxhighlight lang="text">8B 44 24 04 03 44 24 08 C3</syntaxhighlight>
 
;Task:
If different than 32-bit x86, specify the target architecture of the machine code for your example. It may be helpful to also include an assembly version of the machine code for others to reference and understand what is being executed. Then, implement the following in your favorite programming language:
Implement the following in your favorite programming language (take the common lisp code as an example if you wish):
 
<ol>
<li>* Poke the abovenecessary opcodes into a memory pointer</li>location.
* Provide a means to pass two values to the machine code.
<li>Execute it with the following arguments: [ESP+4] => unsigned-byte argument of value 7; [ESP+8] => unsigned-byte argument of value 12; The result would be 19.</li>
* Execute the machine code with the following arguments: unsigned-byte argument of value 7; unsigned-byte argument of value 12; The result would be 19.
<li>Free the Pointer</li>
* Perform any clean up actions that are appropriate for your chosen language (free the pointer or memory allocations, etc.)
</ol>
 
<br><br>
 
=={{header|6502 Assembly}}==
 
We'll execute the following program:
<syntaxhighlight lang="6502asm">LDA #$07
CLC
ADC #$0C
RTS</syntaxhighlight>
 
 
<syntaxhighlight lang="6502asm">main:
LDX #$00 ;initialize array offset to 0
 
LDA #$A9 ;LDA #immediate
STA Array,x ;store at offset 0
INX ;next offset
 
LDA #$07 ;first parameter
STA Array,x ;store at offset 1
INX ;next offset
 
LDA #$18 ;CLC
STA Array,x ;store at offset 2
INX ;next offset
 
LDA #$69 ;ADC #immediate
STA Array,x ;store at offset 3
INX ;next offset
 
LDA #$0C ;second parameter
STA Array,x ;store at offset 4
INX ;next offset
 
LDA #$60 ;RTS
STA Array,x ;store at offset 5
 
 
JMP Array ;assuming we used a JSR to get to main, the RTS at the end of this RAM will return us back to BASIC.
;if array is directly underneath this statement, we can actually omit this JMP entirely
;and execution will simply fall through to the array.
Array:
byte 0,0,0,0,0,0</syntaxhighlight>
 
If you're going to do this in actual programming (which is somewhat common on 8-bit computers for quick interrupt handling), it may be a good idea to know ahead of time the maximum size of your RAM area for machine code and fill it with return statements to avoid crashing.
 
=={{header|68000 Assembly}}==
 
We'll execute the following program:
<syntaxhighlight lang="68000devpac">MOVE.B #7,D0
ADD.B #12,D0
RTS</syntaxhighlight>
And here is the code that sets it up:
<syntaxhighlight lang="68000devpac">LEA CodeArray,A0
MOVE.L #$103C0007,(A0)+ ;MOVE.B #7,D0
MOVE.L #$D03C000C,(A0)+ ;ADD.B #12,D0
MOVE.W #$4E75,(A0)+ ;RTS
JSR CodeArray
 
JMP $ ;halt the cpu, we're done.
 
CodeArray:
DS.B 16 ;16 bytes of padding (this is assumed to be RAM)</syntaxhighlight>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE ADC="$6D"
DEFINE CLC="$18"
DEFINE JSR="$20"
DEFINE LDA="$AD"
DEFINE RTS="$60"
DEFINE STA="$8D"
 
PROC Main()
BYTE ARRAY buf(20)
BYTE a=[19],b=[37],s
CARD addr
 
addr=buf
Poke(addr,CLC) addr==+1
Poke(addr,LDA) addr==+1
PokeC(addr,@a) addr==+2
Poke(addr,ADC) addr==+1
PokeC(addr,@b) addr==+2
Poke(addr,STA) addr==+1
PokeC(addr,@s) addr==+2
Poke(addr,RTS) addr==+1
 
[JSR buf] ;run the machine code stored on buf
 
PrintF("%B+%B=%B%E",a,b,s)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Machine_code.png Screenshot from Atari 8-bit computer]
<pre>
19+37=56
</pre>
 
=={{header|Applesoft BASIC}}==
<syntaxhighlight lang="text">POKE768,169:POKE770,24:POKE771,105:POKE773,133:POKE775,96:POKE774,235:POKE769,7:POKE772,12:CALL768:?PEEK(235)</syntaxhighlight>
 
=={{header|AutoHotkey}}==
Line 29 ⟶ 126:
 
'''MCode4GCC''' ([http://ahkscript.org/boards/viewtopic.php?f=6&t=4642 Forum Thread] | [https://github.com/joedf/MCode4GCC GitHub]) - An MCode generator using the GCC Compiler.
<langsyntaxhighlight AutoHotkeylang="autohotkey">MCode(Var, "8B44240403442408C3")
MsgBox, % DllCall(&Var, "Char",7, "Char",12)
Var := ""
Line 39 ⟶ 136:
Loop % StrLen(hex) // 2
NumPut("0x" . SubStr(hex, 2 * A_Index - 1, 2), code, A_Index - 1, "Char")
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
Line 45 ⟶ 142:
'''Note''' that ''BBC BASIC for Windows'' includes an 80386/80486 assembler as standard!
 
<langsyntaxhighlight lang="bbcbasic"> REM Claim 9 bytes of memory
SYS "GlobalAlloc",0,9 TO code%
 
Line 62 ⟶ 159:
REM Free memory
SYS "GlobalFree",code%
END</langsyntaxhighlight>
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
Line 95 ⟶ 192:
printf("%d\n", test(7,12));
return 0;
}</langsyntaxhighlight>
 
=={{header|COBOL}}==
This solution is a 64-bit adaptation of the task, using the macOS ABI and 64-bit instructions. The assembly code in question is:
 
<langsyntaxhighlight Assemblerlang="assembler">pushq %rbp
movq %rsp, %rbp
movl %edi, -0x4(%rbp)
Line 110 ⟶ 207:
popq %rbp
retq
</syntaxhighlight>
</lang>
The 64-bit "wrapper code" used by the PicoLisp and Go implementations have the parameters <code>7</code> and <code>12</code> baked into it, so I opted for a pure 64-bit implementation rather than manipulating the 64-bit stack to support the 32-bit instructions.
<langsyntaxhighlight COBOLlang="cobol"> >>SOURCE FORMAT IS FIXED
IDENTIFICATION DIVISION.
PROGRAM-ID. MC.
Line 185 ⟶ 282:
 
 
</syntaxhighlight>
</lang>
{{out}}
+0000000019
 
=={{header|Commodore BASIC}}==
 
For Commodore computers, machine language routines are often written to increase speed of a program, provide functionality not otherwise provided for in BASIC, or execute code in the background. It is common to see machine language routines incorporated into BASIC programs for these purposes.
 
The machine code shown for adding two numbers targets the MOS 65xx/85xx architecture (6502, 6510, etc.) and is given as follows:
 
<syntaxhighlight lang="text">Assembly Hexadecimal Decimal
 
CLC 18 24
LDA $2000 AD 00 20 173 0 32
ADC $2001 6D 01 20 109 1 32
STA $2002 8D 02 20 141 2 32
RTS 60 96</syntaxhighlight>
 
# The numbers to be added must be poked into locations $2000 and $2001 (8192 and 8193)
# The machine code is called for execution at $2003 with the SYS statement. (Note, since we are using '''AD'''d with '''C'''arry, we should '''CL'''ear the '''C'''arry flag first to be sure the result is accurate.)
# The result is stored in location $2002 (8194).
# The machine code ''must'' issue a RTS (ReTurn from Subroutine) to allow BASIC to continue.
 
 
Note: This example, using RAM space at $2000, provides a wide range of cross-compatibility across Commodore 8-bit models, and has been tested to work on the Commodore PET (32k), VIC-20 (28k), Commodore 64, Commodore Plus/4, and Commodore 128.
 
No memory management is performed in this example, which would protect the machine code from being overwritten by BASIC. There are more optimal memory locations for the machine code to reside that are not affected by BASIC, however, the locations of such are unique to each model. For example, the range from $C000 to $CFFF (49152 to 53247) on the Commodore 64 is one such ideal location since BASIC memory ends at $9FFF, and there is no overlapping ROM to interfere.
 
<syntaxhighlight lang="gwbasic">10 print chr$(147);
15 ml=8192
20 if peek(ml+3)<>173 and peek(ml+12)<>96 then gosub 100
30 for ad=ml to ml+2:poke ad,0:next
40 poke ml,7:poke ml+1,12
50 print "before:";peek(ml+2)
60 sys ml+3
70 print "after:";peek(ml+2)
80 end
100 rem machine language loader
105 for ad=ml+3 to ml+13
110 read b
115 poke ad,b
120 next
125 return
8195 data 24 :rem clc
8196 data 173,0,32 :rem lda $2000
8199 data 109,1,32 :rem adc $2001
8202 data 141,2,32 :rem sta $2002
8205 data 96 :rem rts</syntaxhighlight>
 
'''Notes about Program'''
 
* Line 20 checks to see if the ML routine has already been loaded into memory. If not, visit the loader routine.
* Line 30 clears the memory locations (sets to zero) for the two addends and the sum.
 
 
{{Output}}
<pre>
BEFORE: 0
AFTER: 19
 
READY.
&#9608;
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">;;Note that by using the 'CFFI' library, one can apply this procedure portably in any lisp implementation;
;; in this code however I chose to demonstrate only the implementation-dependent programs.
 
Line 246 ⟶ 403:
 
(FFI:FOREIGN-FREE POINTER)
</syntaxhighlight>
</lang>
 
=={{header|Cowgol}}==
 
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
# Run machine code at cptr, given two 32-bit arguments,
# return the value returned from EAX.
sub RunCode(cptr: [uint8], arg1: uint32, arg2: uint32): (rslt: uint32) is
# Inline assembly is supported, so this whole rigmarole
# is not even necessary.
# Though note that this (obviously) depends on the assembly back-end used.
# Linux as uses AT&T syntax, so that's what I'm doing here.
# Cowgol supports many processors but this will, obviously, only work
# on x86.
@asm "pushl (",arg1,")"; # Push the two arguments on the stack
@asm "pushl (",arg2,")";
@asm "call *(",cptr,")"; # Call the code at the pointer
@asm "movl %eax, (",rslt,")"; # Store the result in rslt
@asm "popl %eax"; # Clean up the stack
@asm "popl %eax";
end sub;
 
# Store code in an array. This is enough to make it available.
var code: uint8[] := {139, 68, 36, 4, 3, 68, 36, 8, 195};
 
# Use the function
print_i32(RunCode(&code as [uint8], 7, 12)); # this prints 7+12 = 19
print_nl();
 
# As a demonstration, this shows it can be patched at runtime to multiply instead
code[4] := 247;
code[5] := 100;
print_i32(RunCode(&code as [uint8], 7, 12)); # this prints 7*12 = 84
print_nl();</syntaxhighlight>
 
{{out}}
<pre>19
84</pre>
 
=={{header|D}}==
Line 252 ⟶ 448:
 
Generally new operating systems forbid execution of any address unless it's known to contain executable code. This is a basic version that unlike the C entry executes from array memory. This may crash on some operating systems.
<langsyntaxhighlight lang="d">int test(in int a, in int b) pure nothrow @nogc {
/*
mov EAX, [ESP+4]
Line 268 ⟶ 464:
 
test(7, 12).writeln;
}</langsyntaxhighlight>
{{out}}
19
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
With the "Asm" directive, you can insert machine language directly into Delphi code. If you use the assembly language instructions, you don't have to know the opcode numbers. However, it you really want to insert raw binary values, you can use directives like "db" and "dw" to insert raw values.
 
<syntaxhighlight lang="Delphi">
 
function AddNumbers(Num1, Num2: integer): Integer;
{Add two numbers in assembly language}
asm
PUSH EBX
PUSH EDX
MOV ECX,Num1
MOV EDX,Num2
ADD ECX,EDX
MOV Result,ECX
POP EDX
POP EBX
end;
 
 
 
procedure TestAssembly(Memo: TMemo);
var I,J,K: integer;
begin
for I:=1 to 5 do
for J:=1 to 5 do
begin
K:=AddNumbers(I,J);
Memo.Lines.Add(IntToStr(I)+' + '+IntToStr(J)+' = '+IntToStr(K));
end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
1 + 4 = 5
1 + 5 = 6
2 + 1 = 3
2 + 2 = 4
2 + 3 = 5
2 + 4 = 6
2 + 5 = 7
3 + 1 = 4
3 + 2 = 5
3 + 3 = 6
3 + 4 = 7
3 + 5 = 8
4 + 1 = 5
4 + 2 = 6
4 + 3 = 7
4 + 4 = 8
4 + 5 = 9
5 + 1 = 6
5 + 2 = 7
5 + 3 = 8
5 + 4 = 9
5 + 5 = 10
</pre>
 
 
=={{header|Draco}}==
It is possible to call any random area of memory as if it were a function by casting it
to a function of the right type, similar to C. The following example stores the code in
an array. The CP/M version of Draco passes the arguments on the stack in left-to-right
order (so they are popped off in right-to-left order).
 
<syntaxhighlight lang="draco">/* 8080 machine code in an array */
[6] byte add_mc = (
0xC1, /* POP B - get return address */
0xD1, /* POP D - get second argument */
0xE1, /* POP H - get first argument */
0x19, /* DAD D - add arguments */
0xC5, /* PUSH B - push return address back */
0xC9 /* RET - return */
);
 
proc nonrec main() void:
/* Declare a function pointer */
type fn = proc(word a, b) word;
fn add;
/* Pretend the array is actually a function */
add := pretend(add_mc, fn);
/* Call the function and print the result */
writeln(add(12, 7))
corp</syntaxhighlight>
{{out}}
<pre>19</pre>
 
Draco also supports inline machine code directly, using the <code>code()</code>
construct. The machine code is emitted in place during compilation, and cannot
be changed at runtime. It is possible to refer to variables directly, whose
address will be emitted. The linker will even adjust these addresses as required.
 
<syntaxhighlight lang="draco">proc nonrec main() void:
word a, b, c;
/* assign values to the input variables */
a := 12;
b := 7;
/* inline machine code to add A and B
*
* Note that we have to cast each value to a byte,
* because by default, numeric constants are assumed
* to be 16-bit words, and would be emitted as two
* bytes each.
*
* The intent is for the programmer to define byte
* constants corresponding to opcodes, and write
* "assembly", but that is beyond the scope here. */
code(
make(0x2A, byte), a, /* LHLD a - load var A into HL */
make(0xEB, byte), /* XCHG - put it in DE */
make(0x2A, byte), b, /* LHLD b - load var B into HL */
make(0x19, byte), /* DAD D - add DE to HL */
make(0x22, byte), c /* SHLD c - store the result in var C */
);
/* print the result */
writeln(c);
corp</syntaxhighlight>
{{out}}
<pre>19</pre>
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">'' This is an example for the x86 architecture.
Function test (Byval a As Long, Byval b As Long) As Long
Asm
mov eax, [a]
Add eax, [b]
mov [Function], eax
End Asm
End Function
 
Print test(12, 7)
Sleep</syntaxhighlight>
{{out}}
<pre>19</pre>
 
 
=={{header|Go}}==
Line 277 ⟶ 620:
This task requires the use of 'cgo' which enables Go to interface with C code by importing a pseudo-package called "C".
 
Although Go supports both 32-bit and 64-bit architectures, I'm writing this on a 64-bit Ubuntu 1620.04 system. I'vem therefore utilizedusing thex64 PicoLispopcodes entry'srather 'gluethan code'the to enable thex86 (32-bit) codeopcodes tolisted runin the ontask itdescription.
 
There doesn't appear to be a way to cast a pointer to a native buffer to a Go function pointer so that the machine code can be run directly. I've therefore written a C function to perform this step and embedded it in the program which 'cgo' allows us to do.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 302 ⟶ 645:
func main() {
code := []byte{
1440x55, //0x48, Align0x89, 0xe5, 0x89, 0x7d,
1440xfc, 0x89, 0x75, 0xf8, 0x8b, 0x75,
1060xfc, 120x03, //0x75, Prepare0xf8, stack0x89, 0x75,
1840xf4, 70x8b, 00x45, 00xf4, 00x5d, 0xc3,
72, 193, 224, 32,
80,
139, 68, 36, 4, 3, 68, 36, 8, // Rosetta task code
76, 137, 227, // Get result
137, 195,
72, 193, 227, 4,
128, 203, 2,
72, 131, 196, 16, // Clean up stack
195, // Return
}
le := len(code)
Line 326 ⟶ 660:
C.munmap(buf, C.size_t(le))
C.free(codePtr)
}</langsyntaxhighlight>
 
{{out}}
Line 336 ⟶ 670:
{{trans|C}}
Julia cannot execute machine code directly, but can embed C and C++ with the Cxx library.
<langsyntaxhighlight lang="julia">using Cxx
 
cxx"""
Line 374 ⟶ 708:
julia_function = @cxx main()
julia_function()
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 387 ⟶ 721:
 
3. There doesn't appear to be a way to cast a pointer to a native buffer to a Kotlin function pointer so that the machine code can be run. I've therefore written a 'one line' C helper function (in mcode.def) to perform this step and compiled it to a library (mcode.klib) so that it can be called from Kotlin code.
<langsyntaxhighlight Clang="c">// mcode.def
---
 
static inline unsigned char runMachineCode(void *code, unsigned char a, unsigned char b) {
return ((unsigned char (*) (unsigned char, unsigned char))code)(a, b);
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="scala">// Kotlin Native version 0.3
 
import kotlinx.cinterop.*
Line 430 ⟶ 764:
println("$a + $b = ${if(c >= 0) c.toInt() else c + 256}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 444 ⟶ 778:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Buffer DataMem as Long*10
Line 496 ⟶ 830:
}
CheckIt
</syntaxhighlight>
</lang>
 
Using a lambda function with closures two buffers (buffers are objects in M2000 to handle memory blocks). This also add 12 +7 as the task want (but with no pushing to stack, but poke to data buffer)
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Function MyAdd {
Buffer DataMem as Long*2
Line 543 ⟶ 877:
UnsingedAdd=MyAdd()
Print UnsingedAdd(12, 7), UnsingedAdd(500, 100)
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">import posix
 
let MAP_ANONYMOUS {.importc: "MAP_ANONYMOUS", header: "<sys/mman.h>".}: cint
when defined(macosx) or defined(bsd):
const MAP_ANONYMOUS = 0x1000
elif defined(solaris):
const MAP_ANONYMOUS = 0x100
else:
var
MAP_ANONYMOUS {.importc: "MAP_ANONYMOUS", header: "<sys/mman.h>".}: cint
 
proc test(a, b: cint): cint =
# mov EAX, [ESP+4]
# add EAX, [ESP+8]
# ret
var code = [0x8B'u8, 0x44, 0x24, 0x4, 0x3, 0x44, 0x24, 0x8, 0xC3]
 
# create an executable buffer
var buf = mmap(nil, sizeof(code), PROT_READ or PROT_WRITE or PROT_EXEC,
MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
 
# copy code to the buffer
copyMem(addr buf, addr code[0], sizeof(code))
 
# run code
{.emit: "`result` = cast[proc((inta, (*b: cint): (int,cint int))&`{.nimcall.}](buf`)(`a`,` b`);".}
 
# free buffer
discard munmap(buf, sizeof(code))
 
echo test(7, 12)</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
GP can't peek and poke into memory, but PARI can add in those capabilities via [[#C|C]].
{{trans|C}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
Line 608 ⟶ 935:
pari_printf("%d\n", test(7,12));
return 0;
}</langsyntaxhighlight>
 
=={{header|Pascal}}==
Tested under Linux with Freepascal 2.6.4-32BIt ( like the Code used )
cdecl doesn't work in Freepascal under Linux 64-bit
<langsyntaxhighlight lang=" pascal">Program Example66;
{Inspired... program to demonstrate the MMap function. Freepascal docs }
Uses
Line 647 ⟶ 974:
if fpMUnMap(P,Len)<>0 Then
Halt(fpgeterrno);
end.</langsyntaxhighlight>
;output:
<pre>12+7 = 19</pre>
 
=={{header|Phix}}==
Phix has a builtin assembler, which makes the specifics of this task "the hard way to do it".
<lang Phix>atom mem = allocate(9)
<!--<syntaxhighlight lang="phix">(notonline)-->
poke(mem,{#8B,#44,#24,#04,#03,#44,#24,#08,#C3})
<span style="color: #004080;">atom</span> <span style="color: #000000;">mem</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
constant mfunc = define_c_func({},mem,{C_INT,C_INT},C_INT)
<span style="color: #000000;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">#8B</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#44</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#24</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#04</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#03</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#44</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#24</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#08</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#C3</span><span style="color: #0000FF;">})</span>
?c_func(mfunc,{12,7})
<span style="color: #008080;">constant</span> <span style="color: #000000;">mfunc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_c_func</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">},</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">)</span>
free(mem)</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mfunc</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
In Phix the #ilASM statement (which has guards to allow 32/64/WIN/LNX variants) is usually used for inline assembly, for example (but sticking to the task):
<!--<syntaxhighlight lang="phix">-->
<lang Phix>atom mem = allocate(9)
<span style="color: #004080;">atom</span> <span style="color: #000000;">mem</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
poke(mem,{#8B,#44,#24,#04,#03,#44,#24,#08,#C3})
<span style="color: #000000;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">#8B</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#44</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#24</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#04</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#03</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#44</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#24</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#08</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#C3</span><span style="color: #0000FF;">})</span>
integer res
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
#ilASM{ mov eax,[mem]
#ilASM{ mov eax,[mem]
call :%pLoadMint -- eax:=(int32)eax, in case mem>#3FFFFFFF
call :%pLoadMint -- eax:=(int32)eax, in case mem&gt;#3FFFFFFF
push 12
push 712
call eaxpush 7
add esp,8call eax
mov [res],eaxadd }esp,8
mov [res],eax }
?res
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
free(mem)</lang>
<span style="color: #000000;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">)</span>
Better yet, albeit deviating somewhat from the task (and this runs on both 32 and 64 bit):
<!--</syntaxhighlight>-->
<lang Phix>integer res
Better yet, albeit perhaps deviating somewhat from the task, but adhering in spirit, and unlike the above runnable on both 32 and 64 bit:<br><small>(Were you to produce a list.asm from this, using p -d, it would show the x86 bytes above or the x64 equivalent, using a mix of octal and hex representations)</small>
#ilASM{ jmp @f
<!--<syntaxhighlight lang="phix">-->
::add
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
[32]
#ilASM{ jmp @f
mov eax,[esp+4]
::add eax,[esp+8]
[6432]
mov raxeax,[rspesp+84]
add raxeax,[rspesp+168]
[64]
ret mov rax,[rsp+8]
@@: add rax,[rsp+16]
[] push 12
push 7ret
call @@:add
[32] push 12
add esp,8push 7
mov [res],eaxcall :add
[6432]
add rspesp,168
mov [res],raxeax
[64]
} add rsp,16
mov [res],rax
?res</lang>
[]
All three cases output 19
}
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
<!--</syntaxhighlight>-->
In practice I would omit the jmp/labels/call/ret and probably just use registers instead of the stack:
<!--<syntaxhighlight lang="phix">-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
#ilASM{
[32]
mov eax,12
mov edx,7
add eax,edx
mov [res],eax
[64]
mov rax,12
mov rdx,7
add rax,rdx
mov [res],rax
[]
}
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
<!--</syntaxhighlight>-->
All four cases output 19
 
=={{header|PicoLisp}}==
The following runs on 64-bit PicoLisp. Therefore we need some glue code to
interface to the task's 32-bit code.
<langsyntaxhighlight PicoLisplang="picolisp">(setq P
(struct (native "@" "malloc" 'N 39) 'N
# Align
Line 732 ⟶ 1,084:
 
# Free memory
(native "@" "free" NIL P)</langsyntaxhighlight>
Output:
<pre>19</pre>
 
=={{header|PL/M}}==
 
This code runs on an 8080 (or Z80) processor.
 
PL/M does not assume the existence of any operating system features or
come with a standard library, so communicating with the OS actually has
to be done in the same manner as calling (any other) machine language
routines.
 
<syntaxhighlight lang="plm">100H:
 
/* 8080 MACHINE CODE TO ADD TWO BYTES:
79 MOV A,C ; LOAD FIRST ARG INTO ACCUMULATOR
83 ADD E ; ADD SECOND ARG TO ACCUMULATOR
C9 RET ; RETURN */
DECLARE ADD$8080 DATA (79H, 83H, 0C9H);
 
/* THE 8080 PL/M CALLING CONVENTION IS THAT THE
NEXT-TO-LAST ARG IS PUT IN (B)C, THE LAST ARG IN (D)E.
(THE REST ARE IN MEMORY BUT WE DO NOT NEED ANY MORE.)
THE RETURN ARGUMENT SHOULD BE IN THE ACCUMULATOR.
WE CAN DEFINE A WRAPPER PROCEDURE TO DECLARE THE
TYPES OF THE ARGUMENTS. */
 
EXEC$ADD: PROCEDURE (A,B) BYTE;
DECLARE (A,B) BYTE;
/* WE CAN 'GO TO' CONSTANTS OR VARIABLES, BUT NOT TO
EXPRESSIONS. SO WE HAVE TO FETCH THE ADDRESS FIRST. */
DECLARE LOC ADDRESS;
LOC = .ADD$8080;
GO TO LOC;
END EXEC$ADD;
 
/* IN FACT, PL/M DOES NOT COME WITH ANY STANDARD LIBARIES.
IT IS FROM BEFORE THE TIME THAT YOU COULD ASSUME THERE
WOULD EVEN BE AN OPERATING SYSTEM, THOUGH CP/M
(THE PREDECESSOR TO DOS) WOULD QUICKLY BECOME STANDARD.
WE NEED TO USE THIS EXACT TRICK TO GET CP/M TO PRINT THE
RESULT TO THE OUTPUT. LUCKILY (AND NOT COINCIDENTALLY),
THE CP/M SYSCALL ENTRY POINT IS COMPATIBLE WITH THE
PL/M CALLING CONVENTION. */
 
BDOS: PROCEDURE (FUNC, ARG);
DECLARE FUNC BYTE;
DECLARE ARG ADDRESS;
/* 5 IS THE CP/M BDOS ENTRY POINT */
GO TO 5;
END BDOS;
 
/* WE ALSO NEED OUR OWN NUMBER OUTPUT ROUTINE. WE CAN WRITE
IT IN PL/M, THEN USE THE ABOVE ROUTINE TO TELL CP/M
TO PRINT THE RESULT. */
PRINT$NUMBER: PROCEDURE(N);
DECLARE S (4) BYTE INITIAL ('...$');
DECLARE P ADDRESS;
DECLARE (N, C BASED P) BYTE;
/* EXTRACT EACH DIGIT AND WRITE THEM BACKWARDS TO A STRING */
P = .S(3);
DIGIT:
P = P-1;
C = (N MOD 10) + '0';
N = N/10;
IF N > 0 THEN GO TO DIGIT;
 
/* TELL CP/M TO PRINT THE RESULTING STRING */
CALL BDOS(9, P);
END PRINT$NUMBER;
 
/* USING OUR OWN MACHINE CODE WORKS IN THE SAME WAY */
CALL PRINT$NUMBER( EXEC$ADD( 7, 12) ); /* THIS PRINTS 19 */
 
CALL BDOS(0,0); /* EXIT */
EOF</syntaxhighlight>
 
{{out}}
 
<pre>19</pre>
=={{header|PureBasic}}==
<font face="Courier New">Using the Windows API:
</font>
 
<langsyntaxhighlight PureBasiclang="purebasic">CompilerIf #PB_Compiler_Processor <> #PB_Processor_x86
CompilerError "Code requires a 32-bit processor."
CompilerEndIf
Line 784 ⟶ 1,217:
Data.a $8B,$44,$24,$04,$03,$44,$24,$08,$C2,$08,$00
ecode:
EndDataSection</langsyntaxhighlight>
 
=={{header|Python}}==
Line 792 ⟶ 1,225:
The ctypes module is meant for calling existing native code from Python, but you can get it to execute your own bytes with some tricks. The bulk of the code is spent establishing an executable memory area - once that's done, the actual execution takes just a few lines.
 
<langsyntaxhighlight Pythonlang="python">import ctypes
import os
from ctypes import c_ubyte, c_int
Line 829 ⟶ 1,262:
res = func(7,12)
print(res)
</syntaxhighlight>
</lang>
 
=={{header|Quackery}}==
 
This task is a bit of a stretch, but the Quackery engine is a virtual machine, so technically Quackery is an assembly language.
 
Specifically the engine is a stack based processor that does not have direct access to RAM; instead a co-processor mediates requests for dynamically allocated memory. More details in the About Quackery section of Quackery's Category page. (Click on the header for this task.)
 
So, with the limitations that using Hex numbers to indicate opcodes is not possible, and understanding that when a chunk of memory is requested it is addressed by an offset and a reference to the start of the allocated memory (the numerical address of which is not available to the programmer), this is a walkthrough of the process in the Quackery shell.
 
As it is a stack machine arguments are passed via the data stack, reducing the specified task to a single operation; the MOV is not required. Therefore I have substituted a different specification that requires two operators - it is "add two numbers and negate the result".
 
Numbers in Quackery are signed BigIntegers; there are no unsigned numbers, so that part of the task is omitted.
 
Please don't flag this as incorrect - it's the best you'll get.
 
<pre>/O> ( check that + and negate are operators (i.e. op-codes )
... ' + operator? ' negate operator? and if [ say "true"]
...
true
Stack empty.
 
/O> ( create a memory block large enough to hold them, )
... ( filled with zeros )
... 0 2 of
...
 
Stack: [ 0 0 ]
 
/O> ( poke the + operator into place )
... ' + swap 0 poke
...
 
Stack: [ + 0 ]
 
/O> ( poke the negate operator into place )
... ' negate swap 1 poke
...
 
Stack: [ + negate ]
 
/O> ( Using the phrase )
... ( )
... ( ' + ' negate join )
... ( )
... ( would be more idiomatic, but )
... ( the task specifies poking. )
 
Stack: [ + negate ]
 
/O> ( now put two numbers underneath it on the stack )
... 7 12 rot
...
 
Stack: 7 12 [ + negate ]
 
/O> ( and run the machine code )
... do
...
 
Stack: -19
 
/O> ( ta-da! )
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket/base
 
(require ffi/unsafe)
Line 854 ⟶ 1,350:
(function 7 12)
 
(scheme-free-code code)</langsyntaxhighlight>
 
=={{header|Raku}}==
I don't know how to translate this C line <langsyntaxhighlight Clang="c">c = ((int (*) (int, int))buf)(a, b);</langsyntaxhighlight> so cannot solve the task with an idiomatic solution. I have also tried with Go's approach by adding a helper program but it also doesn't work out. Nonetheless I just present the attempt here so perhaps someone can fix that in 10 seconds.
<syntaxhighlight lang="raku" perl6line>use NativeCall;
 
constant PROT_READ = 0x1; #
Line 890 ⟶ 1,386:
}
 
say test 7, 12;</langsyntaxhighlight>
 
In the mean time, here is a less desirable approach by writing a wrapper for the C entry, with the 64 bit instructions from PicoLisp ..
{{trans|C}} test.c
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
Line 918 ⟶ 1,414:
munmap (buf, sizeof(code));
return c;
}</langsyntaxhighlight>
mcode.raku
<syntaxhighlight lang="raku" perl6line>#!/usr/bin/env raku
 
# 20200501 Raku programming solution
Line 931 ⟶ 1,427:
 
say test 7, 12;
</syntaxhighlight>
</lang>
{{out}}<pre>gcc -Wall -fPIC -shared -o LibTest.so test.c
file LibTest.so
Line 941 ⟶ 1,437:
This is heavily inspired by https://www.jonathanturner.org/2015/12/building-a-simple-jit-in-rust.html<br />
Hence, only working on Linux (the only other way to disable memory execution protection on other OSes was to use other crates, which kind of defeats the purpose.)
<langsyntaxhighlight Rustlang="rust">extern crate libc;
 
#[cfg(all(
Line 985 ⟶ 1,481:
println!("Not supported on this platform.");
}
</syntaxhighlight>
</lang>
 
=={{header|S-BASIC}}==
The target CPUs for the 8-bit CP/M machines which supported S-BASIC
are the 8080 and the Z80. The documented approach to
including machine code is to declare a common array sufficient in
size to hold the machine language routine. The common data area starts
at 011A hex. The byte values for the op codes could either
be directly stashed in the array, as here, or more conveniently in the case
of a longer routine, assembled at a starting address of
011Ah and then overlaid into the compiled S-BASIC program using
the debugger DDT.COM. The machine code would be invoked
using the CALL statement, which takes one of two forms. In the
first, the only argument is the starting address of the machine code.
In the second, used here, four variables following the address are mapped to
the 8080's HL, DE, BC, and A_PSW register pairs.
<syntaxhighlight lang = "BASIC">
$constant CODESIZE = 4 rem - size of our ml routine
$constant ML_LOC = 011AH rem - beginning of common data area
 
dim common byte ml_code(CODESIZE)
var hl, de, bc, a_psw = integer
 
comment
The 8080 machine language routine adds two unsigned
8-bit numbers passed as the low-order bytes in the
BC and DE registers, and leaves the result in HL.
end
 
ml_code(1) = 79H rem MOV A,C
ml_code(2) = 83H rem ADD E
ml_code(3) = 6FH rem MOV L,A
ml_code(4) = 0C9H rem RET
 
bc = 7 rem first number
de = 12 rem second number
 
rem - call the routine and display the result (returned in HL)
call (ML_LOC, hl, de, bc, a_psw)
print bc; " plus"; de; " equals"; hl
 
end
</syntaxhighlight>
{{out}}
<pre>
7 plus 12 equals 19
</pre>
 
 
=={{header|Scala}}==
 
{{incomplete|Scala| The text below cannot be considered a contribution that specifically addresses the task, it is rather a subjective judgement. Please either contribute code or remove and place in the talk section of this page. Regards.}}
 
PEEK, POKE and inserting machine opcode makes your system vulnerable which is not quite professional.
 
Considered to be more harmful than useful.
 
=={{header|Scheme}}==
 
 
<syntaxhighlight lang="scheme">
#!/usr/bin/env gosh
#| -*- mode: scheme; coding: utf-8; -*- |#
(use c-wrapper)
(use gauche.uvector)
(use gauche.sequence)
(c-load '("sys/mman.h" "string.h"))
 
;; target architecture is x86_64 aka amd64
;; add 2 ints and return int
;; lea (%rsi,%rdi,1),%eax #x8d #x4 #x3e
;; retq #xc3
(define code #u8(#x8d #x4 #x3e #xc3))
(define buf (mmap 0
(size-of code)
(logior PROT_READ PROT_WRITE PROT_EXEC)
(logior MAP_PRIVATE MAP_ANONYMOUS)
-1
0))
 
(define (main args)
(memcpy buf code (size-of code))
(print ((cast (c-func-ptr <c-uchar> (list <c-uchar> <c-uchar>)) buf) 7 12))
(munmap buf (size-of code))
0)
</syntaxhighlight>
 
=={{header|Smalltalk}}==
Line 1,000 ⟶ 1,576:
 
First we need a way to allocate executable memory (btw. we should probably also care to flush any instruction caches, which I won't go into here);
This is very Smalltalk dialect specific, and probably not supported on other Smalltalks; in ST/X, where inline C-code can be compiled dynamically, we can define it as:
{{works with|Smalltalk/X}}
<langsyntaxhighlight lang="smalltalk">!ExternalBytes class methods!
 
mapExecutableBytes:size
Line 1,018 ⟶ 1,594:
%}.
self primitiveFailed
! !</langsyntaxhighlight>
 
next, we need the correct code; the following presents the x86 version (but do not expect this code to NOT crash the Smalltalk VM, as the calling convention is certainly wrong..)
<langsyntaxhighlight lang="smalltalk">OperatingSystem getCPUType = #'x86' ifTrue:[
code := #[0x8B 0x44 0x24 0x04 0x03 0x44 0x24 0x08 0xC3].
] ifFalse:[
Line 1,042 ⟶ 1,618:
" now call it "
result := func invokeWithArguments:{10 . 20}
</syntaxhighlight>
</lang>
With a few more tricks, it is even possible to install that function as a method in a class; but additional code needs to be generated, to assert that the passed data is correctly boxed/unboxed.
 
Line 1,052 ⟶ 1,628:
Using 64-bit glue code since Swift has limited 32-bit support on x86.
 
<langsyntaxhighlight lang="swift">import Foundation
 
typealias TwoIntsOneInt = @convention(c) (Int, Int) -> Int
Line 1,086 ⟶ 1,662:
 
print(fudge(x: 7, y: 12))
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{trans|C}}
{{libheader|Critcl}}
<langsyntaxhighlight lang="tcl">package require critcl
 
critcl::ccode {
Line 1,120 ⟶ 1,696:
# But now we have our thunk, we can execute arbitrary binary blobs
set code [binary format c* {0x8B 0x44 0x24 0x4 0x3 0x44 0x24 0x8 0xC3}]
puts [runMachineCode $code 7 12]</langsyntaxhighlight>
Note that it would be more common to put that thunk in its own package (e.g., <code>machineCodeThunk</code>) and then just do something like this:
<langsyntaxhighlight lang="tcl">package require machineCodeThunk 1.0
 
set code [binary format c* {0x8B 0x44 0x24 0x4 0x3 0x44 0x24 0x8 0xC3}]
puts [runMachineCode $code 7 12]</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|C}}
Wren is a high-level scripting language and cannot execute machine code directly.
 
However, it is designed for embedding and we can therefore ask the host to do this for us. Here, we use a host program written in C, the language which Wren itself is written in.
<syntaxhighlight lang="wren">/* Machine_code.wren */
class C {
// pass the machine code in string form to the host
foreign static runMachineCode(s, a, b)
}
 
var a = 7
var b = 12
 
// x64 opcodes for this task
var m = [
0x55, 0x48, 0x89, 0xe5, 0x89, 0x7d,
0xfc, 0x89, 0x75, 0xf8, 0x8b, 0x75,
0xfc, 0x03, 0x75, 0xf8, 0x89, 0x75,
0xf4, 0x8b, 0x45, 0xf4, 0x5d, 0xc3
]
 
var s = m.map { |byte| String.fromByte(byte) }.join()
System.print("%(a) + %(b) = %(C.runMachineCode(s, a, b))")</syntaxhighlight>
<br>
We now embed this Wren script in the following C program, compile and run it.
<syntaxhighlight lang="c">/* gcc Machine_code.c -o Machine_code -lwren -lm */
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include "wren.h"
 
unsigned char rmc_helper(const char *code, unsigned char a, unsigned char b, int l) {
void *buf;
unsigned char c;
 
/* copy code to executable buffer */
buf = mmap (0, l, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
memcpy(buf, code, l);
 
/* run code */
c = ((unsigned char (*) (unsigned char, unsigned char))buf)(a, b);
 
/* free buffer */
munmap(buf, l);
 
/* return result to caller */
return c;
}
 
void C_runMachineCode(WrenVM* vm) {
/* unpack arguments passed from Wren */
int len;
const char *code = wrenGetSlotBytes(vm, 1, &len);
unsigned char a = (unsigned char)wrenGetSlotDouble(vm, 2);
unsigned char b = (unsigned char)wrenGetSlotDouble(vm, 3);
 
/* obtain result */
unsigned char c = rmc_helper(code, a, b, len);
/* return result to Wren */
wrenSetSlotDouble(vm, 0, (double)c);
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "runMachineCode(_,_,_)") == 0) {
return C_runMachineCode;
}
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main() {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Machine_code.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
7 + 12 = 19
</pre>
 
=={{header|X86-64 Assembly}}==
===UASM 2.52===
<syntaxhighlight lang="asm">
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Linux Build:
;; $ uasm -elf64 mexec.asm
;; $ gcc -o mexec mexec.o -no-pie
;; With MUSL libc
;; $ musl-gcc -o mexec mexec.o -e main -nostartfiles -no-pie
;;
;; Windows Build:
;; $ uasm64 -win64 mexec.asm
;; $ link /machine:x64 /subsystem:console /release mexec.obj
;; kernel32.lib msvcrt.lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
option casemap:none
option literals:on
 
WIN64 equ 1
LIN64 equ 3
 
ifndef __MEMEXEC_CLASS__
__MEMEXEC_CLASS__ equ 1
 
if @Platform eq WIN64
option dllimport:<kernel32>
HeapAlloc proto fd:qword, flgs:dword, hlen:qword
HeapFree proto fd:qword, flgs:dword, lpmem:qword
GetProcessHeap proto
ExitProcess proto uexit:word
option dllimport:<msvcrt>
printf proto fmt:qword, args:VARARG
memcpy proto d:qword, s:qword, mlen:qword
option dllimport:none
exit equ ExitProcess
elseif @Platform eq LIN64
malloc proto SYSTEMV len:qword
free proto SYSTEMV m:qword
printf proto SYSTEMV fmt:qword, args:VARARG
mprotect proto SYSTEMV m:qword, s:qword, flgs:dword
memcpy proto SYSTEMV d:qword, s:qword, mlen:qword
exit proto SYSTEMV uexit:word
PROT_READ equ 01h
PROT_WRITE equ 02h
PROT_EXEC equ 04h
PROT_NONE equ 00h
PROT_ALL equ PROT_READ + PROT_WRITE + PROT_EXEC
endif
 
CLASS memexec
CMETHOD run
ENDMETHODS
buff db 048h, 089h, 0F8h ;; mov rax, rdi
db 048h, 001h, 0F0h ;; add rax, rsi
db 0C3h ;; ret
mem dq ? ;; Memory address
mlen dq 0 ;; Memory size allocated?
ENDCLASS
 
pmemexec typedef ptr memexec
 
METHOD memexec, Init, <VOIDARG>, <uses rcx>
local tmp:qword
 
mov rbx, thisPtr
assume rbx:ptr memexec
lea rdx, [rbx].buff
invoke printf, CSTR("[mexec->Init] - bytecode addr: 0x%X",10), rdx
mov tmp, rdx
mov [rbx].mlen, sizeof(tmp)
invoke printf, CSTR("[mexec->Init] - bytecode len: %i",10), [rbx].mlen
;; In Built memory allocator, used by the Class extention
;; Uses either HeapAlloc for windows or malloc for everything else.
;; Which is why I didn't use mmap in the first place.
MEMALLOC([rbx].mlen)
.if rax == -1
invoke printf, CSTR("[exec->Init->Error] - Malloc failed with -1",10)
mov rax, rbx
ret
.endif
mov [rbx].mem, rax
invoke printf, CSTR("[mexec->Init] - [rbx].mem addr: 0x%X",10), [rbx].mem
;; Memory wont be executable by default from Malloc, So we make it
;; so with mprotect. Not sure about windows, Might need to use a VirtualProtect
;; call..
if @Platform eq LIN64
invoke mprotect, [rbx].mem, [rbx].mlen, PROT_ALL
.if rax == -1
invoke printf, CSTR("[exec]-Init->Error] - mprotect failed with -1",10)
mov rax, rbx
ret
.endif
endif
invoke printf, CSTR("[mexec->Init] Copying [rbx].buff bytecode to 0x%X",10), [rbx].mem
invoke memcpy, [rbx].mem, addr [rbx].buff, [rbx].mlen
.if rax == -1
invoke printf, CSTR("[mexec->Init->Error] - memcpy failed with -l",10)
mov rax, rbx
ret
.endif
mov rcx, [rbx].mem
mov rax, rbx
assume rbx:nothing
ret
ENDMETHOD
 
METHOD memexec, run, <VOIDARG>, <>, arg1:qword, arg2:qword
mov rbx, thisPtr
assume rbx:ptr memexec
mov rdi, arg1
mov rsi, arg2
call [rbx].mem
assume rbx:nothing
ret
ENDMETHOD
 
METHOD memexec, Destroy, <VOIDARG>, <>
mov rbx, thisPtr
assume rbx:ptr memexec
mov [rbx].mlen, 0
MEMFREE([rbx].mem)
assume rbx:nothing
ret
ENDMETHOD
 
endif ;; __MEMEXEC_CLASS__
.data
a1 dq 7
a2 dq 12
 
.code
main proc
local pmem:ptr memexec
mov pmem, _NEW(memexec)
pmem->run(a1,a2)
invoke printf, CSTR("[pmem->run(%i, %i)] - returned: %i",10), a1, a2, rax
_DELETE(pmem)
invoke exit, 0
ret
main endp
 
end
</syntaxhighlight>
 
=={{header|XPL0}}==
This is for the Raspberry Pi's ARM architecture. The opcodes are effectively "poked" by merely loading the program.
<syntaxhighlight lang="xpl0">func Sum(A, B); \Return sum of A+B
char A, B;
[asm { ldrb r0, A
ldrb r1, B
add r0, r1
strb r0, A
}
return A;
];
 
IntOut(0, Sum(7, 12))</syntaxhighlight>
 
{{out}}
<pre>19</pre>
 
=={{header|Z80 Assembly}}==
<syntaxhighlight lang="z80">;;;;;;;;;;;;;;;;;;; HEADER ;;;;;;;;;;;;;;;;;;;
read "\SrcCPC\winape_macros.asm"
read "\SrcCPC\MemoryMap.asm"
read "\SrcALL\winapeBuildCompat.asm"
read "\SrcALL\lib\z80_opcode_chart.asm"
;;;;;;;;;;;;;;;;;;; PROGRAM ;;;;;;;;;;;;;;;;;;;
org &1000
ld hl,machine_code_area
 
;assembles the following:
;LD A,7
;ADD 12
;DAA
;CALL SHOWHEX
;RET
 
ld (hl),&3E ;LD A,nn
inc hl
ld (hl),7
inc hl
ld (hl),&C6 ;ADD nn
inc hl
ld (hl),12
inc hl
ld (hl),&27 ;DAA
inc hl
ld (hl),&CD ;call
inc hl
ld (hl),&00 ;low byte of address of showhex
inc hl
ld (hl),&11 ;high byte of address of showhex
inc hl
ld (hl),&C9 ;RET
 
;FALLTHROUGH IS INTENTIONAL
machine_code_area:
;0 = nop
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
byte 0,0,0,0,0,0,0,0
 
org &1100
read "\SrcCPC\winape_showhex.asm" ;showhex is at &1100 thanks to the org.
read "\SrcCPC\winape_stringop.asm"</syntaxhighlight>
 
If you were doing this for real, it's much better to define the opcodes as labels so that you don't need to memorize them. (I really wish assemblers let you use instruction names as aliases for data, but I imagine that would make parsing much more difficult. Oh well.)
 
{{omit from|360 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|AArch64 Assembly}}
{{omit from|ARM Assembly}}
{{omit from|Mathematica}}
{{omit from|MIPS Assembly}}
{{omit from|x86 Assembly}}
16

edits