Machine code: Difference between revisions

Add Cowgol
(Add Cowgol)
Line 247:
(FFI:FOREIGN-FREE POINTER)
</lang>
 
=={{header|Cowgol}}==
 
<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();</lang>
 
{{out}}
<pre>19
84</pre>
 
=={{header|D}}==
2,114

edits