Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
32
Task/Machine-code/Cowgol/machine-code.cowgol
Normal file
32
Task/Machine-code/Cowgol/machine-code.cowgol
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
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();
|
||||
Loading…
Add table
Add a link
Reference in a new issue