Machine code: Difference between revisions
Content added Content deleted
Not a robot (talk | contribs) (Add Cowgol) |
|||
Line 247: | Line 247: | ||
(FFI:FOREIGN-FREE POINTER) |
(FFI:FOREIGN-FREE POINTER) |
||
</lang> |
</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}}== |
=={{header|D}}== |