Machine code: Difference between revisions

Added S-BASIC example
(Added S-BASIC example)
 
(5 intermediate revisions by 5 users not shown)
Line 4:
For example, the following assembly language program is given for x86 (32 bit) architectures:
 
<langsyntaxhighlight lang="asm">mov EAX, [ESP+4]
add EAX, [ESP+8]
ret</langsyntaxhighlight>
 
This would translate into the following opcode bytes:
<syntaxhighlight lang="text">139 68 36 4 3 68 36 8 195</langsyntaxhighlight>
 
Or in hexadecimal:
<syntaxhighlight lang="text">8B 44 24 04 03 44 24 08 C3</langsyntaxhighlight>
 
;Task:
Line 26:
 
We'll execute the following program:
<langsyntaxhighlight lang="6502asm">LDA #$07
CLC
ADC #$0C
RTS</langsyntaxhighlight>
 
 
<langsyntaxhighlight lang="6502asm">main:
LDX #$00 ;initialize array offset to 0
 
Line 64:
Array:
byte 0,0,0,0,0,0</langsyntaxhighlight>
 
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.
Line 71:
 
We'll execute the following program:
<langsyntaxhighlight lang="68000devpac">MOVE.B #7,D0
ADD.B #12,D0
RTS</langsyntaxhighlight>
And here is the code that sets it up:
<langsyntaxhighlight lang="68000devpac">LEA CodeArray,A0
MOVE.L #$103C0007,(A0)+ ;MOVE.B #7,D0
MOVE.L #$D03C000C,(A0)+ ;ADD.B #12,D0
Line 84:
 
CodeArray:
DS.B 16 ;16 bytes of padding (this is assumed to be RAM)</langsyntaxhighlight>
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">DEFINE ADC="$6D"
DEFINE CLC="$18"
DEFINE JSR="$20"
Line 112:
 
PrintF("%B+%B=%B%E",a,b,s)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Machine_code.png Screenshot from Atari 8-bit computer]
Line 120:
 
=={{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)</langsyntaxhighlight>
 
=={{header|AutoHotkey}}==
Line 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 136:
Loop % StrLen(hex) // 2
NumPut("0x" . SubStr(hex, 2 * A_Index - 1, 2), code, A_Index - 1, "Char")
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
Line 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 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 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 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 282:
 
 
</syntaxhighlight>
</lang>
{{out}}
+0000000019
Line 292:
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
Line 298:
ADC $2001 6D 01 20 109 1 32
STA $2002 8D 02 20 141 2 32
RTS 60 96</langsyntaxhighlight>
 
# The numbers to be added must be poked into locations $2000 and $2001 (8192 and 8193)
Line 310:
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.
 
<langsyntaxhighlight lang="gwbasic">10 print chr$(147);
15 ml=8192
20 if peek(ml+3)<>173 and peek(ml+12)<>96 then gosub 100
Line 329:
8199 data 109,1,32 :rem adc $2001
8202 data 141,2,32 :rem sta $2002
8205 data 96 :rem rts</langsyntaxhighlight>
 
'''Notes about Program'''
Line 347:
 
=={{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 403:
 
(FFI:FOREIGN-FREE POINTER)
</syntaxhighlight>
</lang>
 
=={{header|Cowgol}}==
 
<langsyntaxhighlight lang="cowgol">include "cowgol.coh";
 
# Run machine code at cptr, given two 32-bit arguments,
Line 438:
code[5] := 100;
print_i32(RunCode(&code as [uint8], 7, 12)); # this prints 7*12 = 84
print_nl();</langsyntaxhighlight>
 
{{out}}
Line 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 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}}==
Line 474 ⟶ 538:
order (so they are popped off in right-to-left order).
 
<langsyntaxhighlight lang="draco">/* 8080 machine code in an array */
[6] byte add_mc = (
0xC1, /* POP B - get return address */
Line 494 ⟶ 558:
/* Call the function and print the result */
writeln(add(12, 7))
corp</langsyntaxhighlight>
{{out}}
<pre>19</pre>
Line 503 ⟶ 567:
address will be emitted. The linker will even adjust these addresses as required.
 
<langsyntaxhighlight lang="draco">proc nonrec main() void:
word a, b, c;
Line 530 ⟶ 594:
/* print the result */
writeln(c);
corp</langsyntaxhighlight>
{{out}}
<pre>19</pre>
Line 536 ⟶ 600:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">'' This is an example for the x86 architecture.
Function test (Byval a As Long, Byval b As Long) As Long
Asm
Line 546 ⟶ 610:
 
Print test(12, 7)
Sleep</langsyntaxhighlight>
{{out}}
<pre>19</pre>
Line 559 ⟶ 623:
 
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 596 ⟶ 660:
C.munmap(buf, C.size_t(le))
C.free(codePtr)
}</langsyntaxhighlight>
 
{{out}}
Line 606 ⟶ 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 644 ⟶ 708:
julia_function = @cxx main()
julia_function()
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 657 ⟶ 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 700 ⟶ 764:
println("$a + $b = ${if(c >= 0) c.toInt() else c + 256}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 714 ⟶ 778:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Buffer DataMem as Long*10
Line 766 ⟶ 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 813 ⟶ 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
Line 838 ⟶ 902:
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 871 ⟶ 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 910 ⟶ 974:
if fpMUnMap(P,Len)<>0 Then
Halt(fpgeterrno);
end.</langsyntaxhighlight>
;output:
<pre>12+7 = 19</pre>
Line 916 ⟶ 980:
=={{header|Phix}}==
Phix has a builtin assembler, which makes the specifics of this task "the hard way to do it".
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<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>
<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>
Line 922 ⟶ 986:
<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>
<!--</langsyntaxhighlight>-->
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):
<!--<langsyntaxhighlight Phixlang="phix">-->
<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>
<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>
Line 937 ⟶ 1,001:
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
<span style="color: #000000;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mem</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
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>
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
#ilASM{ jmp @f
Line 964 ⟶ 1,028:
}
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
<!--</langsyntaxhighlight>-->
In practice I would omit the jmp/labels/call/ret and probably just use registers instead of the stack:
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
#ilASM{
Line 982 ⟶ 1,046:
}
<span style="color: #0000FF;">?</span><span style="color: #000000;">res</span>
<!--</langsyntaxhighlight>-->
All four cases output 19
 
Line 988 ⟶ 1,052:
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 1,020 ⟶ 1,084:
 
# Free memory
(native "@" "free" NIL P)</langsyntaxhighlight>
Output:
<pre>19</pre>
Line 1,033 ⟶ 1,097:
routines.
 
<langsyntaxhighlight lang="plm">100H:
 
/* 8080 MACHINE CODE TO ADD TWO BYTES:
Line 1,100 ⟶ 1,164:
 
CALL BDOS(0,0); /* EXIT */
EOF</langsyntaxhighlight>
 
{{out}}
Line 1,109 ⟶ 1,173:
</font>
 
<langsyntaxhighlight PureBasiclang="purebasic">CompilerIf #PB_Compiler_Processor <> #PB_Processor_x86
CompilerError "Code requires a 32-bit processor."
CompilerEndIf
Line 1,153 ⟶ 1,217:
Data.a $8B,$44,$24,$04,$03,$44,$24,$08,$C2,$08,$00
ecode:
EndDataSection</langsyntaxhighlight>
 
=={{header|Python}}==
Line 1,161 ⟶ 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 1,198 ⟶ 1,262:
res = func(7,12)
print(res)
</syntaxhighlight>
</lang>
 
=={{header|Quackery}}==
Line 1,264 ⟶ 1,328:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket/base
 
(require ffi/unsafe)
Line 1,286 ⟶ 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 1,322 ⟶ 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 1,350 ⟶ 1,414:
munmap (buf, sizeof(code));
return c;
}</langsyntaxhighlight>
mcode.raku
<syntaxhighlight lang="raku" perl6line>#!/usr/bin/env raku
 
# 20200501 Raku programming solution
Line 1,363 ⟶ 1,427:
 
say test 7, 12;
</syntaxhighlight>
</lang>
{{out}}<pre>gcc -Wall -fPIC -shared -o LibTest.so test.c
file LibTest.so
Line 1,373 ⟶ 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 1,417 ⟶ 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}}==
Line 1,426 ⟶ 1,537:
 
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,437 ⟶ 1,578:
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,453 ⟶ 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,477 ⟶ 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,487 ⟶ 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,521 ⟶ 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,555 ⟶ 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}}==
Line 1,567 ⟶ 1,708:
 
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.
<langsyntaxhighlight ecmascriptlang="wren">/* machine_codeMachine_code.wren */
class C {
Line 1,586 ⟶ 1,727:
 
var s = m.map { |byte| String.fromByte(byte) }.join()
System.print("%(a) + %(b) = %(C.runMachineCode(s, a, b))")</langsyntaxhighlight>
<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 */
<lang c>#include <stdlib.h>
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Line 1,615 ⟶ 1,758:
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 */
Line 1,681 ⟶ 1,824:
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "machine_codeMachine_code.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
Line 1,697 ⟶ 1,840:
free(script);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 1,706 ⟶ 1,849:
=={{header|X86-64 Assembly}}==
===UASM 2.52===
<langsyntaxhighlight lang="asm">
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Linux Build:
Line 1,848 ⟶ 1,991:
 
end
</syntaxhighlight>
</lang>
 
=={{header|XPL0}}==
This is for the Raspberry Pi's ARM architecture. The opcodes are effectively "poked" by merely loading the program.
<langsyntaxhighlight XPL0lang="xpl0">func Sum(A, B); \Return sum of A+B
char A, B;
[asm { ldrb r0, A
Line 1,862 ⟶ 2,005:
];
 
IntOut(0, Sum(7, 12))</langsyntaxhighlight>
 
{{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|6502 Assembly|Assembly is just machine code in a human-readable form, so you're already there}}
{{omit from|68000 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
Line 1,877 ⟶ 2,071:
{{omit from|MIPS Assembly}}
{{omit from|x86 Assembly}}
{{omit from|Z80 Assembly}}
16

edits