Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ass-js

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ass-js - npm Package Compare versions

Comparing version 1.0.3 to 1.0.4

22

abi.js

@@ -7,6 +7,6 @@ "use strict";

this.abi = null;
this.lbl = null;
this.clobbered = [];
this.stackFrame = false;
this.locals = 0;
this.lbl = null; // Label is created for every function.
this.clobbered = []; // Clobbered registers.
this.stackFrame = false; // Whether to create a new stack frame.
this.locals = 0; // Stack size reserved for function local variables.
}

@@ -18,4 +18,7 @@ Function.prototype._ = function (bodyCallback) {

this.abi.code.insert(this.lbl);
// Prologue
this.abi.prologue(this.stackFrame, this.clobbered, this.locals);
// Function body
bodyCallback();
// Epilogue
this.abi.epilogue(this.stackFrame, this.clobbered, this.locals);

@@ -27,9 +30,16 @@ return this;

exports.Function = Function;
// Implements platform and architecture specific ABI conventions, for example,
// calls the right syscall instruction, be it `syscall`, `sysenter`, `int 0x80` or anything else;
// `push`es and `pop`s function arguments to stack according to calling conventions, etc.
var Abi = (function () {
function Abi(code) {
this.FunctionClass = Function;
// rax, rdi, rsi, rdx, r10, r8, r9
this.syscallArgs = [o.rax, o.rdi, o.rsi, o.rdx, o.r10, o.r8, o.r9];
this.notSyscallArgs = [o.rbx, o.rcx, o.r11, o.r12, o.r13, o.r14, o.r15];
// args: rdi, rsi, rdx, rcx, r8, r9 + stack
this.callArgs = [o.rdi, o.rsi, o.rdx, o.rcx, o.r8, o.r9];
// scratch: rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11
this.scratchRegisters = [o.rax, o.rdi, o.rsi, o.rdx, o.rcx, o.r8, o.r9, o.r10, o.r11];
// preserved: rbx, rsp, rbp, r12, r13, r14, r15
this.preservedRegisters = [o.rbx, o.rsp, o.rbp, o.r12, o.r13, o.r14, o.r15];

@@ -74,2 +84,3 @@ this.code = code;

if (stackFrame || locals) {
// this.code._('enter', [locals, 0]);
this.code._('push', o.rbp);

@@ -98,2 +109,3 @@ this.code._('mov', [o.rbp, o.rsp]);

if (stackFrame || locals) {
// this.code._('leave');
this.code._('mov', [o.rsp, o.rbp]);

@@ -107,2 +119,3 @@ this.code._('pop', o.rbp);

if (preserve === void 0) { preserve = this.scratchRegisters; }
// Save registers.
for (var j = 0; j < preserve.length; j++) {

@@ -133,2 +146,3 @@ var reg = preserve[j];

this.code._('call', expr);
// Restore registers.
for (var j = preserve.length - 1; j > -1; j--) {

@@ -135,0 +149,0 @@ var reg = preserve[j];

@@ -28,3 +28,11 @@ "use strict";

function Instruction() {
// 3322222222221111111111
// 10987654321098765432109876543210
this.tpl = 0;
// ||||||||||||||||||||||||||||||||
// ||||||IPUBWS
// |||||| L UAL
// |||||| N
// ||||00
// XXXX ---> Condition
this.cond = COND.AL;

@@ -66,2 +74,4 @@ this.A = 0;

_super.apply(this, arguments);
// 3322222222221111111111
// 10987654321098765432109876543210
this.tpl = 8388608;

@@ -68,0 +78,0 @@ }

@@ -11,4 +11,4 @@ "use strict";

this.expr = [];
this.operandSize = operand_1.SIZE.D;
this.addressSize = operand_1.SIZE.D;
this.operandSize = operand_1.SIZE.D; // Default operand size.
this.addressSize = operand_1.SIZE.D; // Default address size.
this.ClassInstruction = i.Instruction;

@@ -18,3 +18,3 @@ this.ClassInstructionSet = i.InstructionSet;

this.AlignExpression = i.Align;
this.littleEndian = true;
this.littleEndian = true; // Which way to encode constants by default.
this.label(start);

@@ -160,3 +160,3 @@ }

this.expr[index] = expr;
expr.calcOffsetMaxAndOffset();
expr.calcOffsetMaxAndOffset(); // 1st pass
return expr;

@@ -240,2 +240,3 @@ };

var encoding = typeof b === 'string' ? b : 'ascii';
// var buf = Buffer.from(a, encoding);
var buf = new Buffer(a, encoding);

@@ -348,7 +349,26 @@ octets = Array.prototype.slice.call(buf, 0);

};
// Expressions are compiled in 3 passes:
//
// - *1st pass* -- maximum offset `maxOffset` for each expression is computed, some expression might not know
// their size jet, not all expressions are known, future references. First pass is when user performs insertion of commands.
// - *2nd pass* -- all expressions known now, each expression should pick its right size, exact `offset` is computed for each expression.
// - *3rd pass* -- now we know exact `offset` of each expression, so in this pass we fill in the addresses.
Code.prototype.compile = function () {
// 1st pass is performed as instructions are `insert`ed, `.offsetMax` is calculated, and possibly `.offset`.
// Instructions without size can now determine their size based on `.offsetMax` and
// calculate their real `.offset`.
this.do2ndPass();
// Offsets are now know, here we evaluate references.
return this.do3rdPass();
};
Code.prototype.do2ndPass = function () {
// We probably cannot skip this 2nd pass, as instructions might change their sizes after inserted,
// for example, when `.lock()` prefix is added.
// var last = this.expr[this.expr.length - 1];
// var all_offsets_known = last.offset >= 0;
//
// Edge case when only the last Expression has variable size.
// var all_sizes_known = last.bytes() >= 0;
//
// if(all_offsets_known && all_sizes_known) return; // Skip 2nd pass.
var prev = this.expr[0];

@@ -363,2 +383,8 @@ prev.offset = 0;

}
// var bytes = prev.bytes();
// if(bytes === i.SIZE_UNKNOWN)
// throw Error(`Instruction [${j}] does not have size.`);
// ins.offset = prev.offset + bytes;
// Need to call method, as `InstructionSet` contains multiple `Instruction`s,
// that all need offset updated of picked instruction.
ins.calcOffset();

@@ -374,3 +400,3 @@ prev = ins;

ins.evaluate();
code = ins.write(code);
code = ins.write(code); // 3rd pass
}

@@ -377,0 +403,0 @@ return code;

@@ -15,2 +15,3 @@ "use strict";

this.operandSize = def.s;
// Operand template.
this.operands = [];

@@ -24,2 +25,3 @@ if (def.ops && def.ops.length) {

var flattened = operand.reduce(function (a, b) {
// Determine operand size from o.Register operands
var cur_size = o.SIZE.NONE;

@@ -66,4 +68,7 @@ if (b instanceof o.Register) {

else if (typeof tpl === 'function') {
var OperandClass = tpl;
var OperandClass = tpl; // as typeof o.Operand;
if (OperandClass.name.indexOf('Relative') === 0) {
// Here we cannot yet check any sizes even cannot check if number
// fits the immediate size because we will have to rebase the o.Relative
// to the currenct instruction Expression.
if (o.isTnumber(operand))

@@ -84,3 +89,3 @@ return OperandClass;

else
throw TypeError('Invalid operand definition.');
throw TypeError('Invalid operand definition.'); // Should never happen.
};

@@ -163,3 +168,3 @@ Def.prototype.matchOperandTemplates = function (templates, operand) {

opcode: this.opcode,
opcodeHex: this.opcode.toString(16),
opcodeHex: this.opcode.toString(16)
};

@@ -207,4 +212,7 @@ if (this.operandSize)

var group_defaults = defs[0], definitions = defs.slice(1);
// If only one object provided, we treat it as instruction definition rather then
// as group defaults.
if (!definitions.length)
definitions = [group_defaults];
// Mnemonic.
if (!group_defaults.mn)

@@ -236,3 +244,3 @@ group_defaults.mn = this.mnemonic;

mnemonic: this.mnemonic,
definitions: instructions,
definitions: instructions
};

@@ -285,2 +293,10 @@ };

};
// create(table: t.TableDefinition, defaults: t.Definition): this {
// for(var mnemonic in table) {
// var group = new this.DefGroupClass(this, mnemonic);
// group.createDefinitions(table[mnemonic], defaults);
// this.groups[mnemonic] = group;
// }
// return this;
// }
DefTable.prototype.toJson = function () {

@@ -322,2 +338,3 @@ var json = {};

if (tpl) {
// If registers are 5-bit wide, we can encode them only with EVEX, not VEX.
if (def.vex && ops.has5bitRegister())

@@ -324,0 +341,0 @@ return;

@@ -14,5 +14,8 @@ "use strict";

function Expression() {
// Index where instruction was inserted in `Code`s buffer.
this.index = 0;
this.length = exports.SIZE_UNKNOWN;
// Byte offset of the instruction in compiled machine code.
this.offset = exports.OFFSET_UNKNOWN;
// Same as `offset` but for instructions that we don't know byte size yet we assume `MAX_SIZE`.
this.offsetMax = exports.OFFSET_UNKNOWN;

@@ -24,2 +27,3 @@ this.code = null;

};
// Size in bytes of the instruction.
Expression.prototype.bytes = function () {

@@ -36,7 +40,10 @@ return this.length;

};
// Whether the size of this `Expression` is determined.
Expression.prototype.hasSize = function () {
return this.bytes() !== exports.SIZE_UNKNOWN;
};
// Called after new expression is inserted into `Code`.
Expression.prototype.build = function () {
};
// Calculated during the first pass, when expressions are inserted into `Code` block.
Expression.prototype.calcOffsetMaxAndOffset = function () {

@@ -68,2 +75,3 @@ if (this.index === 0) {

};
// Calculated during the second pass, when all expressions determine their final size.
Expression.prototype.calcOffset = function () {

@@ -78,2 +86,3 @@ if (this.offset !== exports.OFFSET_UNKNOWN)

if (offset === exports.OFFSET_UNKNOWN)
// this.offset = OFFSET_UNKNOWN;
throw Error("Instruction [" + (this.index - 1) + "] does not have offset.");

@@ -83,2 +92,3 @@ else {

if (bytes === exports.SIZE_UNKNOWN)
// this.offset = OFFSET_UNKNOWN;
throw Error("Instruction [" + (this.index - 1) + "] does not have size.");

@@ -135,2 +145,4 @@ else

this.length = 0;
// if((typeof name !== 'string') || !name)
// throw TypeError('Label name must be a non-empty string.');
this.symbol = new o.Symbol(this, 0, name);

@@ -283,2 +295,3 @@ }

exports.Data = Data;
// A pre-filled template with some binary data.
var Template = (function (_super) {

@@ -305,2 +318,4 @@ __extends(Template, _super);

exports.Template = Template;
// Expressions that have operands, operands might reference (in case of `Relative`) other expressions, which
// have not been insert into code yet, so we might not know the how those operands evaluate on first two passes.
var ExpressionVariable = (function (_super) {

@@ -311,6 +326,19 @@ __extends(ExpressionVariable, _super);

_super.call(this);
this.ops = null;
this.ops = null; // Operands provided by user.
this.isEvaluated = false;
this.ops = ops;
}
// canEvaluate() {
// for(var op of this.ops.list) {
// if(op instanceof Relative) {
// var rel = op as Relative;
// if(rel.target.offset === OFFSET_UNKNOWN) return false;
// }
// }
// return true;
// }
// Whether this Expression is ready to be written to binary buffer.
// canEvaluate() {
// return true;
// }
ExpressionVariable.prototype.evaluate = function () {

@@ -347,2 +375,4 @@ this.isEvaluated = true;

var rel = op;
// num = list[j] = rel.rebaseOffset(this);
// num = rel.rebaseOffset(this);
num = rel.evaluate(this);

@@ -394,2 +424,3 @@ }

exports.DataVariable = DataVariable;
// Expression which, not only has variable operands, but which may evaluate to different sizes.
var ExpressionVolatile = (function (_super) {

@@ -404,2 +435,3 @@ __extends(ExpressionVolatile, _super);

};
// If `Expression` can generate different size machine code this method forces it to pick one.
ExpressionVolatile.prototype.getFixedSizeExpression = function () {

@@ -411,2 +443,3 @@ return this;

exports.ExpressionVolatile = ExpressionVolatile;
// Aligns data to some byte boundary.
var Align = (function (_super) {

@@ -417,2 +450,3 @@ __extends(Align, _super);

this.length = exports.SIZE_UNKNOWN;
// Different size templates we use to fill in the empty bytes, templates grow sequentially by one byte in size.
this.templates = [

@@ -480,4 +514,4 @@ [0x00],

_super.apply(this, arguments);
this.def = null;
this.opts = null;
this.def = null; // Definition on how to construct this instruction.
this.opts = null; // Instruction options provided by user.
}

@@ -509,3 +543,3 @@ Instruction.prototype.build = function () {

});
cmt = "0x" + octets.join(', 0x') + (" " + this.bytes() + " bytes");
cmt = "0x" + octets.join(', 0x') + (" " + this.bytes() + " bytes"); // + ' / ' + this.def.toString();
}

@@ -517,2 +551,4 @@ return this.formatToString(margin, expression, cmt);

exports.Instruction = Instruction;
// Wrapper around multiple instructions when different machine instructions can be used to perform the same task.
// For example, `jmp` with `rel8` or `rel32` immediate, or when multiple instruction definitions match provided operands.
var InstructionSet = (function (_super) {

@@ -524,4 +560,4 @@ __extends(InstructionSet, _super);

this.insn = [];
this.picked = -1;
this.opts = null;
this.picked = -1; // Index of instruction that was eventually chosen.
this.opts = null; // Instruction options provided by user.
this.matches = matches;

@@ -546,3 +582,3 @@ this.opts = opts;

var ins = this.insn[j];
var rel = ins.ops.list[m];
var rel = ins.ops.list[m]; // Relative of instruction.
var success = rel.canHoldMaxOffset(this);

@@ -600,2 +636,3 @@ if (success) {

return null;
// Pick the shortest instruction if we know all instruction sizes, otherwise don't pick any.
var size = exports.SIZE_UNKNOWN;

@@ -639,2 +676,4 @@ var isize = 0;

if (typeof tpl === 'number') {
// Skip number
// `int 3`, for example, is just `0xCC` instruction.
ops.list[j] = null;

@@ -693,2 +732,6 @@ }

var lines = [];
// for(var j = 0; j < this.insn.length; j++) {
// if(this.insn[j].ops) lines.push(this.insn[j].toString(margin, hex));
// else lines.push(' ' + this.matches.list[j].def.toString());
// }
for (var _i = 0, _a = this.matches.list; _i < _a.length; _i++) {

@@ -695,0 +738,0 @@ var match = _a[_i];

@@ -60,2 +60,3 @@ "use strict";

}
// export type Tnumber = number|number64|number128|number256|number512|number1024|number2048;
function isTnumber(num) {

@@ -70,6 +71,9 @@ if (typeof num === 'number')

exports.isTnumber = isTnumber;
// General operand used in our assembly "language".
var Operand = (function () {
function Operand() {
// Size in bits.
this.size = SIZE.ANY;
}
// Convenience method to get `Register` associated with `Register` or `Memory`.
Operand.prototype.reg = function () {

@@ -93,2 +97,5 @@ return null;

exports.Operand = Operand;
// ## Constant
//
// Constants are everything where we directly type in a `number` value.
var Constant = (function (_super) {

@@ -101,2 +108,3 @@ __extends(Constant, _super);

this.value = 0;
// Each byte as a `number` in reverse order.
this.octets = [];

@@ -131,2 +139,3 @@ this.signed = true;

var clazz = this.signed ? Constant.sizeClass(value) : Constant.sizeClassUnsigned(value);
/* JS integers are 53-bit, so split here `number`s over 32 bits into [number, number]. */
if (clazz === SIZE.Q)

@@ -205,2 +214,5 @@ this.setValue64([util_1.UInt64.lo(value), util_1.UInt64.hi(value)]);

throw Error("Already larger than " + size + " bits, cannot zero-extend.");
// TODO: Make it work with 128-bit numbers too, below.
// We know it is not number64, because we don't deal with number larger than 64-bit,
// and if it was 64-bit already there would be nothing to extend.
var value = this.value;

@@ -378,2 +390,5 @@ if (size === SIZE.Q) {

exports.ImmediateUnsigned64 = ImmediateUnsigned64;
// ## Registers
//
// `Register` represents one of `%rax`, `%rbx`, etc. registers.
var Register = (function (_super) {

@@ -383,3 +398,3 @@ __extends(Register, _super);

_super.call(this);
this.id = 0;
this.id = 0; // Number value of register.
this.name = 'reg';

@@ -419,2 +434,5 @@ this.id = id;

exports.Register = Register;
// ## Memory
//
// `Memory` is RAM addresses which `Register`s can *dereference*.
var Memory = (function (_super) {

@@ -448,2 +466,3 @@ __extends(Memory, _super);

exports.Memory = Memory;
// Operand which needs `evaluation`, it may be that it cannot evaluate on first two passes.
var Variable = (function (_super) {

@@ -453,3 +472,3 @@ __extends(Variable, _super);

_super.apply(this, arguments);
this.result = null;
this.result = null; // Result of evaluation.
}

@@ -462,2 +481,3 @@ Variable.prototype.canEvaluate = function (owner) {

};
// Evaluate approximately during 2nd pass.
Variable.prototype.evaluatePreliminary = function (owner) {

@@ -476,2 +496,3 @@ return 0;

exports.isTvariable = isTvariable;
// Relative jump targets for jump instructions.
var Relative = (function (_super) {

@@ -498,2 +519,3 @@ __extends(Relative, _super);

return this.result = this.rebaseOffset(owner) - owner.bytes();
// return this.result = this.rebaseOffset(owner);
};

@@ -512,6 +534,10 @@ Relative.prototype.evaluatePreliminary = function (owner) {

Relative.prototype.cast = function (RelativeClass) {
// cast(RelativeClass: typeof Relative) {
this.size = RelativeClass.size;
// return new RelativeClass(this.target, this.offset);
return this;
};
Relative.prototype.rebaseOffset = function (new_target) {
// if(expr.code !== this.expr.code)
// throw Error('Rebase from different code blocks not implemented yet.');
if (new_target.offset === -1)

@@ -521,3 +547,6 @@ throw Error('Expression has no offset, cannot rebase.');

};
// Recalculate relative offset given a different Expression.
// rebase(target: Expression): Relative {
Relative.prototype.rebase = function (target) {
// return new Relative(target, this.rebaseOffset(expr));
this.offset = this.rebaseOffset(target);

@@ -593,2 +622,3 @@ this.target = target;

exports.Symbol = Symbol;
// Collection of operands an `Expression` might have.
var Operands = (function () {

@@ -599,3 +629,3 @@ function Operands(list, size) {

this.list = [];
this.size = SIZE.ANY;
this.size = SIZE.ANY; // Size of each operand.
this.size = size;

@@ -614,2 +644,3 @@ this.list = list;

var i = require('./instruction');
// Wrap `Expression` into `Relative`.
for (var j = 0; j < ops.length; j++) {

@@ -631,2 +662,3 @@ if (ops[j] instanceof instruction_1.Expression) {

};
// Wrap `Expression` into `Relative`.
Operands.prototype.normalizeExpressionToRelative = function () {

@@ -642,4 +674,6 @@ var i = require('./instruction');

Operands.prototype.validateSize = function () {
// Verify operand sizes.
for (var _i = 0, _a = this.list; _i < _a.length; _i++) {
var op = _a[_i];
// We can determine operand size only by Register; Memory and Immediate and others don't tell us the right size.
if (op instanceof Register) {

@@ -737,2 +771,4 @@ if (this.size !== SIZE.ANY) {

};
// EVEX may encode up to 4 operands, 32 registers, so register can be up to 5-bits wide,
// we need to check for that because in that case we cannot use VEX.
Operands.prototype.has5bitRegister = function () {

@@ -739,0 +775,0 @@ for (var j = 0; j < 4; j++) {

2

package.json
{
"name": "ass-js",
"description": "Assembler.js",
"version": "1.0.3",
"version": "1.0.4",
"keywords": [

@@ -6,0 +6,0 @@ "x86",

"use strict";
var operand_1 = require('./operand');
exports.S = operand_1.SIZE;
// Operands
exports.r = operand_1.Register;

@@ -20,2 +21,3 @@ exports.m = operand_1.Memory;

exports.rel32 = operand_1.Relative32;
// Global defaults
exports.defaults = { o: 0x00, mn: '', s: exports.S.NONE, ops: null };

@@ -9,1 +9,2 @@ "use strict";

console.log(bin);
// console.log(ass.x86.x64.Code.table.toString());

@@ -34,2 +34,4 @@ "use strict";

UInt64.joinToNumber = function (hi, lo) {
// if ((lo !== lo|0) && (lo !== (lo|0) + 4294967296)) throw new Error ("lo out of range: "+lo);
// if ((hi !== hi|0) && hi >= 1048576) throw new Error ("hi out of range: "+hi);
if (lo < 0)

@@ -36,0 +38,0 @@ lo += 4294967296;

@@ -28,2 +28,3 @@ "use strict";

var bySize = group.groupBySize();
// Create methods with size postfix, like: pushq, pushd, pushw, etc..
var _loop_2 = function(s) {

@@ -44,2 +45,3 @@ var size = parseInt(s);

}
// Create general method where we determine operand size from profided operands.
ctx[mnemonic] = function () {

@@ -95,2 +97,3 @@ var ui_ops = [];

var def = matches.list[j].def;
// Check mode of CPU.
if (!(this.mode & def.mode)) {

@@ -100,2 +103,4 @@ matches.list.splice(j, 1);

}
// If EVEX-specific options provided by user,
// remove instruction definition matches that don't have EVEX prefix.
var needs_evex = opts.mask || (typeof opts.z !== 'undefined');

@@ -110,2 +115,9 @@ if (needs_evex) {

};
// Displacement is up to 4 bytes in size, and 8 bytes for some specific MOV instructions, AMD64 Vol.2 p.24:
//
// > The size of a displacement is 1, 2, or 4 bytes.
//
// > Also, in 64-bit mode, support is provided for some 64-bit displacement
// > and immediate forms of the MOV instruction. See “Immediate Operand Size” in Volume 1 for more
// > information on this.
Code.prototype.mem = function (disp) {

@@ -112,0 +124,0 @@ if (typeof disp === 'number')

@@ -39,2 +39,3 @@ "use strict";

}
// 256.66.0F3A.W0 => {L: 1, pp: 1, mmmmm: 1, W: 0}
Def.parseVexString = function (vstr) {

@@ -47,4 +48,5 @@ var vdef = {

W: 1,
WIG: false,
WIG: false
};
// vvvv: NDS, NDD, DDS
if (vstr.indexOf('NDS') > -1)

@@ -56,6 +58,8 @@ vdef.vvvv = 'NDS';

vdef.vvvv = 'DDS';
// L: 128, 256, LIG, LZ
if (vstr.indexOf('256') > -1)
vdef.L = 1;
else if (vstr.indexOf('512') > -1)
vdef.L = 2;
vdef.L = 2; // EVEX
// pp: 66, F2, F3
if (vstr.indexOf('.66.') > -1)

@@ -67,2 +71,3 @@ vdef.pp = 1;

vdef.pp = 2;
// mmmmm: 0F, 0F3A, 0F38
if (vstr.indexOf('0F38') > -1)

@@ -73,5 +78,7 @@ vdef.mmmmm = 2;

else if (vstr.indexOf('0F') > -1)
vdef.mmmmm = 1;
vdef.mmmmm = 1; // Could still be 2-byte VEX prefix
// W: W0, W1
if (vstr.indexOf('W0') > -1)
vdef.W = 0;
// WIG
if (vstr.indexOf('WIG') > -1)

@@ -85,3 +92,3 @@ vdef.WIG = true;

Def.prototype.matchOperandTemplate = function (tpl, operand) {
var OperandClass = tpl;
var OperandClass = tpl; // as typeof o.Operand;
if ((typeof OperandClass === 'function') && (OperandClass.name.indexOf('Immediate') === 0)) {

@@ -88,0 +95,0 @@ if (!operand_1.isTnumber(operand))

@@ -64,2 +64,7 @@ "use strict";

exports.Align = Align;
// ## x86_64 `Instruction`
//
// `Instruction` object is created using instruction `Definition` and `Operands` provided by the user,
// out of those `Instruction` generates `InstructionPart`s, which then can be packaged into machine
// code using `.write()` method.
var Instruction = (function (_super) {

@@ -69,2 +74,3 @@ __extends(Instruction, _super);

_super.apply(this, arguments);
// Instruction parts.
this.pfxOpSize = null;

@@ -77,4 +83,4 @@ this.pfxAddrSize = null;

this.prefixes = [];
this.pfxEx = null;
this.opcode = new p.Opcode;
this.pfxEx = null; // One of REX, VEX, EVEX prefixes, only one allowed.
this.opcode = new p.Opcode; // required
this.modrm = null;

@@ -84,2 +90,4 @@ this.sib = null;

this.immediates = [];
// Direction for register-to-register `MOV` operations, whether REG field of Mod-R/M byte is destination.
// We set this to `false` to be compatible with GAS assembly, which we use for testing.
this.regToRegDirectionRegIsDst = false;

@@ -97,3 +105,3 @@ }

this.pfxEx = null;
this.opcode = new p.Opcode;
this.opcode = new p.Opcode; // required
this.modrm = null;

@@ -161,2 +169,3 @@ this.sib = null;

Instruction.prototype.getFixedSizeExpression = function () {
// Determine size of displacement
this.fixDisplacementSize();

@@ -167,3 +176,3 @@ return _super.prototype.getFixedSizeExpression.call(this);

this.ops.evaluate(this);
var max = 2;
var max = 2; // Up to 2 immediates.
for (var j = 0; j < max; j++) {

@@ -173,5 +182,7 @@ var rel = this.ops.getRelative(j);

var res = rel.result;
// var res = (rel.result as number) - this.bytes();
this.immediates[j].value.setValue(res);
}
}
// Evaluate displacement variable.
if (this.displacement && this.displacement.value.variable) {

@@ -295,2 +306,3 @@ var value = this.displacement.value;

this.createEvexPrefix();
// Mandatory prefixes required by op-code.
if (this.def.prefixes) {

@@ -306,2 +318,3 @@ for (var _i = 0, _a = this.def.prefixes; _i < _a.length; _i++) {

Instruction.prototype.createVexPrefix = function () {
// These bits in VEX are inverted, so they actually all mean "0" zeros.
var R = 1, X = 1, B = 1, vvvv = 15;

@@ -313,3 +326,3 @@ var pos = this.def.opEncoding.indexOf('v');

throw Error("Could not find Register operand at position " + pos + " to encode VEX.vvvv");
vvvv = (~reg.get4bitId()) & 15;
vvvv = (~reg.get4bitId()) & 15; // Inverted
}

@@ -322,3 +335,3 @@ pos = this.def.opEncoding.indexOf('r');

if (reg.idSize() > 3)
R = 0;
R = 0; // Inverted
}

@@ -329,3 +342,3 @@ pos = this.def.opEncoding.indexOf('m');

if (reg && (reg.idSize() > 3))
B = 0;
B = 0; // Inverted
}

@@ -352,4 +365,4 @@ var mem = this.ops.getMemoryOperand();

throw Error("Could not find Register operand at position " + pos + " to encode EVEX.vvvv");
evex.vvvv = (~reg.get4bitId()) & 15;
evex.Vp = reg.id & 16 ? 0 : 1;
evex.vvvv = (~reg.get4bitId()) & 15; // Inverted
evex.Vp = reg.id & 16 ? 0 : 1; // Inverted
}

@@ -363,5 +376,5 @@ pos = this.def.opEncoding.indexOf('r');

if (id_size > 3)
evex.R = 0;
evex.R = 0; // Inverted
if (id_size > 4) {
evex.Rp = 0;
evex.Rp = 0; // Inverted
if (reg.id & 8)

@@ -378,5 +391,5 @@ evex.R = 0;

if (reg.idSize() > 3)
evex.B = 0;
evex.B = 0; // Inverted
if (reg.idSize() > 4) {
evex.X = 0;
evex.X = 0; // Inverted
if (reg.id & 8)

@@ -392,5 +405,5 @@ evex.B = 0;

if (mem.base && (mem.base.idSize() > 3))
evex.B = 0;
evex.B = 0; // Inverted
if (mem.index && (mem.index.idSize() > 3))
evex.X = 0;
evex.X = 0; // Inverted
}

@@ -402,2 +415,3 @@ if (this.opts.mask)

};
// Set mask register for `EVEX` instructions.
Instruction.prototype.mask = function (k) {

@@ -411,2 +425,3 @@ if (!(this.pfxEx instanceof p.PrefixEvex))

};
// Set `z` bit for `EVEX` instructions.
Instruction.prototype.z = function (value) {

@@ -425,2 +440,3 @@ if (value === void 0) { value = 1; }

if (def.regInOp) {
// We have register encoded in op-code here.
if (!dst || (!dst.isRegister()))

@@ -431,2 +447,3 @@ throw TypeError("Operation needs destination Register.");

else {
// Direction bit `d`
if (this.def.opcodeDirectionBit) {

@@ -437,2 +454,3 @@ var direction = p.Opcode.DIRECTION.REG_IS_DST;

}
// *reg-to-reg* operation
if ((dst instanceof o.Register) && (src instanceof o.Register)) {

@@ -460,6 +478,8 @@ if (this.regToRegDirectionRegIsDst)

var has_opreg = (this.def.opreg > -1);
var dst_in_modrm = !this.def.regInOp && !!dst;
var dst_in_modrm = !this.def.regInOp && !!dst; // Destination operand is NOT encoded in main op-code byte.
if (has_opreg || dst_in_modrm) {
// var reg_is_dst = !!(this.opcode.op & p.Opcode.DIRECTION.REG_IS_DST);
var reg_is_dst = this.def.opEncoding[0] !== 'm' ? true : false;
if (has_opreg) {
// If we have `opreg`, then instruction has up to one operand.
reg = this.def.opreg;

@@ -477,2 +497,3 @@ var r = this.ops.getRegisterOperand();

else {
// Reg-to-reg instruction;
if ((encoding.length === 2) && (dst instanceof o.Register) && (src instanceof o.Register)) {

@@ -495,2 +516,3 @@ mod = p.Modrm.MOD.REG_TO_REG;

else {
// var r: o.Register = this.op.getRegisterOperand(this.regToRegDirectionRegIsDst);
var r = this.ops.getRegisterOperand(this.regToRegDirectionRegIsDst ? 0 : 1);

@@ -529,2 +551,6 @@ if (!r)

}
// `o.Memory` class makes sure that ESP cannot be a SIB index register and
// that EBP always has displacement value even if 0x00.
// Memory operand can be encoded in only one way (Modrm.rm + SIB) so we
// ignore here `def.opEncoding` field.
var m = this.ops.getMemoryOperand();

@@ -541,6 +567,9 @@ if (!m) {

throw TypeError('Memory Index reference needs Scale factor.');
// dispX
// We use `disp32` with SIB byte version because the version without SIB byte
// will be used for RIP-relative addressing.
if (!m.base && !m.index && m.displacement) {
m.displacement.signExtend(o.DisplacementValue.SIZE.DISP32);
mod = p.Modrm.MOD.INDIRECT;
rm = p.Modrm.RM.NEEDS_SIB;
rm = p.Modrm.RM.NEEDS_SIB; // SIB byte follows
this.modrm = new p.Modrm(mod, reg, rm);

@@ -551,2 +580,6 @@ this.length++;

}
// [BASE]
// [BASE] + dispX
// `o.Memory` class makes sure that EBP always has displacement value even if 0x00,
// so EBP will not appear here.
if (m.base && !m.index) {

@@ -556,2 +589,4 @@ mod = p.Modrm.getModDispSize(m);

m.displacement.signExtend(o.DisplacementValue.SIZE.DISP32);
// SIB byte follows in `[RSP]` case, and `[RBP]` is impossible as RBP
// always has a displacement, [RBP] case is used for RIP-relative addressing.
rm = m.base.get3bitId();

@@ -563,2 +598,3 @@ this.modrm = new p.Modrm(mod, reg, rm);

}
// [BASE + INDEX x SCALE] + dispX
if (m.base || m.index) {

@@ -569,3 +605,3 @@ mod = p.Modrm.getModDispSize(m);

m.displacement.signExtend(o.DisplacementValue.SIZE.DISP32);
rm = p.Modrm.RM.NEEDS_SIB;
rm = p.Modrm.RM.NEEDS_SIB; // SIB byte follows
this.modrm = new p.Modrm(mod, reg, rm);

@@ -594,2 +630,4 @@ this.length++;

I = m.index.get3bitId();
// RSP register cannot be used as index, `o.Memory` class already ensures it
// if used in normal way.
if (I === p.Sib.INDEX_NONE)

@@ -615,3 +653,5 @@ throw Error("Register " + m.index.toString() + " cannot be used as SIB index.");

if (m.displacement.variable) {
this.lengthMax += o.DisplacementValue.SIZE.DISP32 / 8;
// Displacement will be at least 1 byte,
// but we skip `this.length` for now.
this.lengthMax += o.DisplacementValue.SIZE.DISP32 / 8; // max 4 bytes
}

@@ -625,2 +665,4 @@ else {

else if (this.modrm && this.sib && (this.sib.B === p.Sib.BASE_NONE)) {
// Some SIB byte encodings require displacement, if we don't have displacement yet
// add zero displacement.
var disp = null;

@@ -649,3 +691,3 @@ switch (this.modrm.mod) {

Instruction.prototype.createImmediates = function () {
var max = 2;
var max = 2; // Up to 2 immediates.
for (var j = 0; j < max; j++) {

@@ -655,2 +697,14 @@ var imm = this.ops.getImmediate(j);

if (imm) {
// If immediate does not have concrete size, use the size of instruction operands.
// if(imm.constructor === o.Immediate) {
// var ImmediateClass = this.def.getImmediateClass();
// if(ImmediateClass) imm = new ImmediateClass(imm.value, imm.signed);
// else {
// var size = this.op.size;
// imm = o.Immediate.factory(size, imm.value, imm.signed);
// imm.extend(size);
// }
// }
// if (this.displacement && (this.displacement.value.size === SIZE.Q))
// throw TypeError(`Cannot have Immediate with ${SIZE.Q} bit Displacement.`);
immp = new p.Immediate(imm);

@@ -678,2 +732,4 @@ this.immediates[j] = immp;

exports.Instruction = Instruction;
// Wrapper around multiple instructions when different machine instructions can be used to perform the same task.
// For example, `jmp` with `rel8` or `rel32` immediate, or when multiple instruction definitions match provided operands.
var InstructionSet = (function (_super) {

@@ -680,0 +736,0 @@ __extends(InstructionSet, _super);

@@ -35,6 +35,8 @@ "use strict";

_super.prototype.setValue32.call(this, value);
/* Make sure `Displacement` is 1 or 4 bytes, not 2. */
// if(this.size > DisplacementValue.SIZE.DISP8) this.zeroExtend(DisplacementValue.SIZE.DISP32);
};
DisplacementValue.SIZE = {
DISP8: operand_1.SIZE.B,
DISP32: operand_1.SIZE.D,
DISP32: operand_1.SIZE.D
};

@@ -44,2 +46,5 @@ return DisplacementValue;

exports.DisplacementValue = DisplacementValue;
// ## Registers
//
// `Register` represents one of `%rax`, `%rbx`, etc. registers.
var Register = (function (_super) {

@@ -78,2 +83,3 @@ __extends(Register, _super);

};
// Whether the register is one of `%r8`, `%r9`, etc. extended registers.
Register.prototype.isExtended = function () {

@@ -270,2 +276,5 @@ return this.id > 7;

exports.RegisterDr = RegisterDr;
// # Scale
//
// `Scale` used in SIB byte in two bit `SCALE` field.
var Scale = (function (_super) {

@@ -287,2 +296,5 @@ __extends(Scale, _super);

exports.Scale = Scale;
// ## Memory
//
// `Memory` is RAM addresses which `Register`s can *dereference*.
var Memory = (function (_super) {

@@ -306,2 +318,3 @@ __extends(Memory, _super);

};
// Case memory to some size.
Memory.prototype.cast = function (size) {

@@ -320,2 +333,3 @@ var mem = Memory.factory(size);

return this.index;
// throw Error('No backing register.');
return null;

@@ -331,2 +345,3 @@ };

}
// RBP, EBP etc.. always need displacement for ModRM and SIB bytes.
var is_ebp = (regfile_1.R64.RBP & 7) === base.get3bitId();

@@ -437,2 +452,3 @@ if (is_ebp && !this.displacement)

exports.Memory512 = Memory512;
// Collection of operands an instruction might have.
var Operands = (function (_super) {

@@ -451,2 +467,16 @@ __extends(Operands, _super);

};
// getRegisterOperand(dst_first = true): Register {
// var [dst, src] = this.list;
// var first, second;
// if(dst_first) {
// first = dst;
// second = src;
// } else {
// first = src;
// second = dst;
// }
// if(first instanceof Register) return first as Register;
// if(second instanceof Register) return second as Register;
// return null;
// }
Operands.prototype.hasImmediate = function () {

@@ -475,2 +505,3 @@ return !!this.getImmediate();

exports.Operands = Operands;
// ## Export Registers
function validateRegId(id, min, max, Clazz) {

@@ -477,0 +508,0 @@ if (typeof id !== 'number')

@@ -9,2 +9,16 @@ "use strict";

var o = require('./operand');
// # x86_64 Instruction
//
// Each CPU instruction is encoded in the following form, where only
// *Op-code* byte is required:
//
// |-------------------------------------------------|--------------------------------------------|
// | Instruction | Next instruction |
// |-------------------------------------------------|--------------------------------------------|
// |byte 1 |byte 2 |byte 3 |byte 4 |byte 5 |
// |---------|---------|---------|---------|---------| ...
// |REX |Op-code |Mod-R/M |SIB |Immediat | ...
// |---------|---------|---------|---------|---------| ...
// |optional |required |optional |optional |optional |
// |-------------------------------------------------|
var InstructionPart = (function () {

@@ -42,2 +56,3 @@ function InstructionPart() {

var PREFIX = exports.PREFIX;
// Prefixes that consist of a single static byte.
var PrefixStatic = (function (_super) {

@@ -89,2 +104,3 @@ __extends(PrefixStatic, _super);

}
// static supported = ['cmps', 'cmpsb', 'cmpbd', 'cmpsw', 'scas', 'scasb', 'scasd', 'scasw'];
PrefixRepe.supported = ['cmps', 'scas'];

@@ -99,2 +115,3 @@ return PrefixRepe;

}
// static supported = ['cmps', 'cmpsb', 'cmpsd', 'cmpsw', 'scas', 'scasb', 'scasd', 'scasw'];
PrefixRepne.supported = ['cmps', 'scas'];

@@ -104,2 +121,3 @@ return PrefixRepne;

exports.PrefixRepne = PrefixRepne;
// Lock prefix for performing atomic memory operations.
var PrefixLock = (function (_super) {

@@ -115,2 +133,18 @@ __extends(PrefixLock, _super);

exports.PrefixLock = PrefixLock;
// ## REX
//
// REX is an optional prefix used for two reasons:
//
// 1. For 64-bit instructions that require this prefix to be used.
// 2. When using extended registers: r8, r9, r10, etc..; r8d, r9d, r10d, etc...
//
// REX byte layout:
//
// 76543210
// .1..WRXB
// .......B <--- R/M field in Mod-R/M byte, or BASE field in SIB byte addresses one of the extended registers.
// ......X <---- INDEX field in SIB byte addresses one of the extended registers.
// .....R <----- REG field in Mod-R/M byte addresses one of the extended registers.
// ....W <------ Used instruction needs REX prefix.
// .1 <--------- 0x40 identifies the REX prefix.
var PrefixRex = (function (_super) {

@@ -132,2 +166,27 @@ __extends(PrefixRex, _super);

exports.PrefixRex = PrefixRex;
// ### 2-byte VEX:
// 76543210
// 11000100
//
// 76543210
// ||||||pp ---> pp
// |||||L -----> L
// |vvvv ------> vvvv
// R ----------> R
//
// ### 3-byte VEX:
// 76543210
// 11000101
//
// 76543210
// |||mmmmm ---> mmmmm
// ||B --------> B
// |X ---------> X
// R ----------> R
//
// 76543210
// ||||||pp ---> pp
// |||||L -----> L
// |vvvv ------> vvvv
// W ----------> W
var PrefixVex = (function (_super) {

@@ -141,8 +200,9 @@ __extends(PrefixVex, _super);

_super.call(this);
this.bytes = 2;
this.R = 1;
this.X = 1;
this.bytes = 2; // VEX can be either 2 or 3 bytes.
// R, X, B, W and vvvv are inverted.
this.R = 1; // Must be 1, if not used, otherwise wrong instruction.
this.X = 1; // Must be 1, if not used, otherwise wrong instruction.
this.B = 1;
this.W = 1;
this.vvvv = 15;
this.vvvv = 15; // must be 0b1111, if not used, otherwise CPU will #UD
this.mmmmm = 0;

@@ -156,3 +216,3 @@ this.L = 0;

if (vexdef.WIG)
this.W = 0;
this.W = 0; // When WIG "W ignored", set to "0" to make compatible with GAS.
this.R = R;

@@ -172,7 +232,7 @@ this.X = X;

if (this.bytes === 2) {
arr.push(197);
arr.push(197); // 0xC5
arr.push((this.R << 7) | (this.vvvv << 3) | (this.L << 2) | this.pp);
}
else {
arr.push(196);
arr.push(196); // 0xC4
arr.push((this.R << 7) | (this.X << 6) | (this.B << 5) | this.mmmmm);

@@ -186,3 +246,3 @@ arr.push((this.W << 7) | (this.vvvv << 3) | (this.L << 2) | this.pp);

xF2: 3,
xF3: 2,
xF3: 2
};

@@ -192,3 +252,3 @@ PrefixVex.MMMMM = {

x0F3A: 3,
x0F: 1,
x0F: 1
};

@@ -198,2 +258,25 @@ return PrefixVex;

exports.PrefixVex = PrefixVex;
// EVEX is 4 bytes:
// 62H
//
// 76543210
// ||||||mm ---> mm
// ||||00 -----> always 00
// |||~ -------> R-prime = Rp
// ||B --------> B
// |X ---------> X
// R ----------> R
//
// 76543210
// ||||||pp ---> pp
// |||||1 -----> always 1
// |vvvv-------> vvvv
// W ----------> W
//
// 76543210
// |||||aaa ---> aaa
// ||||~ ------> V-prime = Vp
// |||b -------> b
// |LL --------> LL
// z ----------> z
var PrefixEvex = (function (_super) {

@@ -203,15 +286,17 @@ __extends(PrefixEvex, _super);

_super.call(this);
this.R = 1;
this.X = 1;
this.B = 1;
this.W = 1;
this.vvvv = 15;
this.pp = 0;
this.mm = 0;
this.Rp = 1;
this.z = 0;
this.LL = 0;
this.b = 0;
this.Vp = 1;
this.aaa = 0;
// VEX includes
this.R = 1; // VEX.R - Inverted
this.X = 1; // VEX.X - Inverted
this.B = 1; // VEX.B - Inverted
this.W = 1; // VEX.W - Inverted
this.vvvv = 15; // VEX.vvvv - Inverted
this.pp = 0; // VEX.pp
this.mm = 0; // Low 2 bits of VEX.mmmmm
// New in EVEX
this.Rp = 1; // REX.R extension - Inverted
this.z = 0; // Zeroing/merging
this.LL = 0; // Like VEX.L but extended to 2 bits.
this.b = 0; // Broadcast/RC/SAE context
this.Vp = 1; // VEX.vvvv exntension - Inverted
this.aaa = 0; // Opmask register ID
this.LL = evexdef.L;

@@ -232,2 +317,23 @@ this.mm = evexdef.mmmmm & 3;

exports.PrefixEvex = PrefixEvex;
// ## Op-code
//
// Primary op-code of the instruction. Often the lower 2 or 3 bits of the
// instruction op-code may be set independently.
//
// `d` and `s` bits, specify: d - direction of the instruction, and s - size of the instruction.
// - **s**
// - 1 -- word size
// - 0 -- byte size
// - **d**
// - 1 -- register is destination
// - 0 -- register is source
//
// 76543210
// ......ds
//
// Lower 3 bits may also be used to encode register for some instructions. We set
// `.regInOp = true` if that is the case.
//
// 76543210
// .....000 = RAX
var Opcode = (function (_super) {

@@ -237,2 +343,3 @@ __extends(Opcode, _super);

_super.apply(this, arguments);
// Main op-code value.
this.op = 0;

@@ -248,2 +355,3 @@ }

Opcode.prototype.write = function (arr) {
// Op-code can be up to 3 bytes long.
var op = this.op;

@@ -257,12 +365,13 @@ if (op > 0xFFFF)

};
Opcode.MASK_SIZE = 16777214;
Opcode.MASK_DIRECTION = 16777213;
Opcode.MASK_OP = 16777208;
/* Now we support up to 3 byte instructions */
Opcode.MASK_SIZE = 16777214; // `s` bit
Opcode.MASK_DIRECTION = 16777213; // `d` bit
Opcode.MASK_OP = 16777208; // When register is encoded into op-code.
Opcode.SIZE = {
BYTE: 0,
WORD_OR_DOUBLE: 1,
WORD_OR_DOUBLE: 1
};
Opcode.DIRECTION = {
REG_IS_SRC: 0,
REG_IS_DST: 2,
REG_IS_DST: 2
};

@@ -272,2 +381,11 @@ return Opcode;

exports.Opcode = Opcode;
// ## Mod-R/M
//
// Mod-R/M is an optional byte after the op-code that specifies the direction
// of operation or extends the op-code.
//
// 76543210
// .....XXX <--- R/M field: Register or Memory
// ..XXX <------ REG field: Register or op-code extension
// XX <--------- MOD field: mode of operation
var Modrm = (function (_super) {

@@ -299,2 +417,3 @@ __extends(Modrm, _super);

};
// Two bits of `MOD` field in `Mod-R/M` byte.
Modrm.MOD = {

@@ -304,7 +423,11 @@ INDIRECT: 0,

DISP32: 2,
REG_TO_REG: 3,
REG_TO_REG: 3
};
Modrm.RM = {
// When this value is encoded in R/M field, SIB byte has to follow Mod-R/M byte.
NEEDS_SIB: regfile_1.R64.RSP & 7,
INDIRECT_DISP: regfile_1.R64.RBP & 7,
// When this value is encoded in R/M field, and MOD is 0b00 = INDIRECT,
// disp32 bytes have to follow Mod-R/M byte. But not in long-mode,
// in long-mode it is used for RIP-relative adressing.
INDIRECT_DISP: regfile_1.R64.RBP & 7
};

@@ -314,2 +437,28 @@ return Modrm;

exports.Modrm = Modrm;
// ## SIB
//
// SIB (scale-index-base) is optional byte used when dereferencing memory
// with complex offset, like when you do:
//
// mov rax, [rbp + rdx * 8]
//
// The above operation in SIB byte is encoded as follows:
//
// rbp + rdx * 8 = BASE + INDEX * USERSCALE
//
// Where `USERSCALE` can only be 1, 2, 4 or 8; and is encoded as follows:
//
// USERSCALE (decimal) | SCALE (binary)
// ------------------- | --------------
// 1 | 00
// 2 | 01
// 4 | 10
// 8 | 11
//
// The layout of SIB byte:
//
// 76543210
// .....XXX <--- BASE field: base register address
// ..XXX <------ INDEX field: address of register used as scale
// XX <--------- SCALE field: specifies multiple of INDEX: USERSCALE * INDEX
var Sib = (function (_super) {

@@ -348,3 +497,6 @@ __extends(Sib, _super);

};
// When index set to 0b100 it means INDEX = 0 and SCALE = 0.
Sib.INDEX_NONE = regfile_1.R64.RSP & 7;
// If Modrm.mod = 0b00, BASE = 0b101, means no BASE.
// if Modrm.mod is 0b01 or 0b10, use RBP + disp8 or RBP + disp32, respectively.
Sib.BASE_NONE = regfile_1.R64.RBP & 7;

@@ -354,2 +506,3 @@ return Sib;

exports.Sib = Sib;
// ## Displacement
var Displacement = (function (_super) {

@@ -369,2 +522,5 @@ __extends(Displacement, _super);

exports.Displacement = Displacement;
// ## Immediate
//
// Immediate constant value that follows other instruction bytes.
var Immediate = (function (_super) {

@@ -371,0 +527,0 @@ __extends(Immediate, _super);

@@ -18,2 +18,3 @@ "use strict";

var MODE = exports.MODE;
// Instructins
(function (INS) {

@@ -27,2 +28,3 @@ INS[INS["NONE"] = 0] = "NONE";

var INS = exports.INS;
// Extensions
(function (EXT) {

@@ -72,2 +74,3 @@ EXT[EXT["NONE"] = 0] = "NONE";

exports.M = MODE;
// Operands
exports.r = operand_1.Register;

@@ -108,10 +111,17 @@ exports.r8 = operand_1.Register8;

exports.zmm_zmm_zmmm = [exports.zmm, exports.zmm, exports.zmmm];
// x86 global defaults
exports.defaults = util_1.extend({}, t.defaults, { ds: table_1.S.D, lock: false, or: -1, i: null, r: false, dbit: false, rex: null, mr: true, rep: false, repne: false,
pfx: null, vex: null, evex: null, en: 'rm', mod: exports.M.ALL, ext: null });
// Instruction are divided in groups, each group consists of list
// of possible instructions. The first object is NOT an instruction
// but defaults for the group.
exports.table = {
cpuid: [{ o: 0x0FA2 }],
// INT Software interrupt
int: [{},
// CC INT 3 NP Valid Valid Interrupt 3—trap to debugger.
{ o: 0xCC, ops: [3] },
// CD ib INT imm8 I Valid Valid Interrupt vector specified by immediate byte.
{ o: 0xCD, ops: [table_1.immu8] },
],
]
};

@@ -17,2 +17,3 @@ "use strict";

Instruction.prototype.needs32To64OperandSizeChange = function () {
// Default operand size in x64 mode is 32 bits.
return this.def.operandSize === operand_1.SIZE.Q;

@@ -22,3 +23,3 @@ };

if (this.pfxEx)
return false;
return false; // VEX or EVEX already set
if (this.def.rex)

@@ -28,5 +29,9 @@ return true;

return false;
// if(!this.ops.hasRegisterOrMemory()) return false;
if (this.ops.hasExtendedRegister())
return true;
var _a = this.ops.list, dst = _a[0], src = _a[1];
// sil, dil, spl, bpl
// if(((dst instanceof o.Register8) && !(dst instanceof o.Register8High) && (dst.id >= r.R8.SPL) && (dst.id <= r.R8.DIL)) ||
// ((src instanceof o.Register8) && !(src instanceof o.Register8High) && (src.id >= r.R8.SPL) && (src.id <= r.R8.DIL))) return true;
if ((dst === o.sil) || (dst === o.dil) || (dst === o.spl) || (dst === o.bpl) ||

@@ -55,3 +60,3 @@ (src === o.sil) || (src === o.dil) || (src === o.spl) || (src === o.bpl))

if (pos > -1) {
var m = this.ops.getMemoryOperand();
var m = this.ops.getMemoryOperand(); // Memory operand is only one.
if (m) {

@@ -85,2 +90,9 @@ if (m.base && (m.base.idSize() > 3))

};
// Adding RIP-relative addressing in long mode.
//
// > In the 64-bit mode, any instruction that uses ModRM addressing can use RIP-relative addressing.
//
// > Without RIP-relative addressing, ModRM instructions address memory relative to zero. With RIP-relative
// > addressing, ModRM instructions can address memory relative to the 64-bit RIP using a signed
// > 32-bit displacement.
Instruction.prototype.createModrm = function () {

@@ -91,2 +103,3 @@ var mem = this.ops.getMemoryOperand();

throw TypeError('RIP-relative addressing does not support index and scale addressing.');
// Encode `Modrm.reg` field.
var reg = 0;

@@ -118,2 +131,3 @@ if (this.def.opreg > -1) {

if (mem && (typeof mem == 'object') && (mem.base instanceof o.RegisterRip)) {
// RIP-relative addressing has always 4-byte displacement.
if (!mem.displacement)

@@ -120,0 +134,0 @@ mem.disp(0);

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc