I've been tinkering with Javascript and x86_64 assembly code and in
doing so, I've tried to achieve a syntax in Javascript as close as
possible to the AT&T syntax so that writting assembly code feels almost
like inline assembly with gcc.
I have not extensively surveyed all instructions yet but here is an
example of what it might look like. The javascript notation and the
corresponding assembly code in AT&T syntax are shown side-by-side:
var a = new x86_Assembler();
a.
add ($(-8), ESP). // addl $-8,%esp maintain 16 byte
alignment for Mach!:
push (EAX). // push %eax
mov (_16(ESP), EAX). // movl 16(%esp),%eax get pointer to handlers
call (_12(EAX)). // call *12(%eax) call handlers[1], printf
add ($(12), ESP). // addl $12,%esp maintain 16 byte alignment
add ($(-4), ESP). // addl $-4,%esp maintain 16 byte alignment
push ($(11)). // push $11
dup (). // MACRO: duplicate top
of stack
mov (_16(ESP), EAX). // movl 16(%esp),%eax get pointer to handlers
call (_16(EAX)). // call *16(%eax) call handlers[2], add
add ($(12), ESP). // addl $12,%esp maintain 16 byte alignment
ret ();
The example above covers usage of immediate values, registers, memory
accesses on 0,1 and 2 operands instructions. Notice how by having each
instruction function return the "this" object, all instructions functions
can be chained together. Also notice that "$", "_", "_12" and "_16" are
functions which return either and immediate, or a memory access object.
Finally, "ESP" and "EAX" are register objects.
One interesting thing to note is the possibility to use "macros" of
assembly instructions such as shown by the usage of "dup". Such macros
could be installed on the "a" object for a one shot usage, therefore
being limited to the scope of the "a" variable, without polluting its
prototype. A definition of dup could be:
a.dup = function ()
{
return this.
mov (_(ESP), EAX). // movl (%esp), %eax get top of stack value
add ($(-4), ESP). // addl $-4, %esp add space on stack
for the value
mov (EAX, _(ESP)); // movl %eax, (%esp) copy value on top of
stack
}
Other more useful macros could be promoted to the prototype object.
To achieve that kind of syntax without polluting the global object we
could use the following idiom:
function () // A function or method on an object, or an
anonymous function
{ // used as a local namespace
// Definitions of used methods and objects
const $ = x86_Assembler.prototype.$;
const ESP = x86_Assembler.prototype.register.ESP;
const EAX = x86_Assembler.prototype.register.EAX;
const _ = x86_Assembler.prototype.memory._;
const _12 = x86_Assembler.prototype.memory._12;
const _16 = x86_Assembler.prototype.memory._16;
var a = new x86_Assembler(); // Can be defined here or outside the
function
// Macro definitions such as "dup"
// Some assembly code here
}; // When used as a namespace, it should be
called right away
I will survey more extensively other instruction usages to see if there
are corner cases.
Erick