Mail Archives: djgpp-workers/1997/09/14/22:05:51
--Message-Boundary-28453
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Mail message body
These are relative to the first 2.02 alpha (31 aug?).
- most 386/486 instructions now implemented (a few still missing, I
have to find out which ones, mostly variants)
- sign extension used whenever possible for offsets and immediate
values.
- compiles with `-Wall -Werror'
- structure and untion definitions (see my djgpp.asm for details)
- `.sys' file type support (you still have to code the device header
by hand though)
- 32 bit addressing.
There may be others, but I can't remeber them.
Bill
--
Leave others their otherness.
--Message-Boundary-28453
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'djasm.patch'
*** djasm.y~ Tue Aug 13 02:43:10 1996
--- djasm.y Fri Sep 12 22:18:24 1997
***************
*** 9,14 ****
--- 9,16 ----
#include <coff.h>
#include <fcntl.h>
#include <time.h>
+ #include <ctype.h>
+ #include <unistd.h>
#define SMALL_EXE_HEADER 0
#if SMALL_EXE_HEADER
***************
*** 21,26 ****
--- 23,31 ----
#define YYERROR_VERBOSE
+ #define MAX(a,b) ((a)>(b)?(a):(b))
+ #define MIN(a,b) ((a)<(b)?(a):(b))
+
void yyerror(char *s);
#define OUT_exe 0
***************
*** 29,34 ****
--- 34,40 ----
#define OUT_h 3
#define OUT_inc 4
#define OUT_s 5
+ #define OUT_sys 6
char *ext_types[] = {
"exe",
***************
*** 37,42 ****
--- 43,49 ----
"h",
"inc",
"ah",
+ "sys",
0
};
***************
*** 98,103 ****
--- 105,111 ----
#define REL_abs32 1
#define REL_16 2
#define REL_8 3
+ #define REL_abs8 4
typedef struct Patch {
struct Patch *next;
***************
*** 110,127 ****
Symbol *get_symbol(char *name, int create);
Symbol *set_symbol(Symbol *sym, int value);
Symbol *zerosym;
struct {
int regs;
int offset;
int nsyms;
Symbol *syms[10];
! } _modrm = { 0, 0, 0 };
unsigned char sreg_overrides[] = {
0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65
};
void emit(void *v, int len);
void emitb(int b);
void emitw(int w);
--- 118,151 ----
Symbol *get_symbol(char *name, int create);
Symbol *set_symbol(Symbol *sym, int value);
Symbol *zerosym;
+ void destroy_symbol(Symbol *sym, int undef_error);
+ void destroy_locals(void);
+ void add_struct_element(Symbol *s);
+ int set_structor_symbols(Symbol *ele, Symbol *struc, int base, int type);
+ void emit_struct(Symbol *ele, int tp, Symbol *struc);
+ void build_struct(Symbol *ele, int tp, Symbol *struc);
+ int undefs = 0;
struct {
int regs;
int offset;
+ int addr16;
+ int addr32;
int nsyms;
Symbol *syms[10];
! } _modrm = { 0, 0, 0, 0, 0 };
unsigned char sreg_overrides[] = {
0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65
};
+ int struct_tp;
+ int struct_pc;
+ char *struct_sym;
+
+ int yylex(void);
+ int yylex1(void);
+
void emit(void *v, int len);
void emitb(int b);
void emitw(int w);
***************
*** 129,137 ****
--- 153,163 ----
void emits(Symbol *s, int offset, int rel);
void modrm(int mod, int reg, int rm);
void reg(int reg);
+ void addr32(int sib);
void sortsyms();
int istemp(char *symname, char which);
+ int islocal(char *symname);
void do_sreg_pop(int sreg);
void do_sreg_push(int sreg);
void do_align(int p2, int val);
***************
*** 159,165 ****
%type <sym> ID
%type <relsym> constID
! %type <i> const offset
%token <sym> KID UID
--- 185,191 ----
%type <sym> ID
%type <relsym> constID
! %type <i> const offset scaledindex
%token <sym> KID UID
***************
*** 177,194 ****
%token <i> JCC JCCL JCXZ LOOP SETCC
%token <i> SHIFT SHLRD
%token <i> ONEBYTE TWOBYTE ASCADJ
! %token <i> BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7
! %token ALIGN
! %token BSS
%token CALL CALLF COPYRIGHT
! %token DB DD DEC DECB DECD DECW DUP DW
%token IN INC INCB INCD INCW INT INCLUDE
%token JMPW JMPB JMPF
! %token LINKCOFF
%token MOV MOVB MOVD MOVW
%token IMUL IMULB IMULD IMULW
%token ORG OUT
! %token POP POPW POPD PUSH PUSHW PUSHD
%token RCS_ID RET RETF RETD RETFD
%token STACK START
%token TEST TESTB TESTD TESTW TYPE
--- 203,220 ----
%token <i> JCC JCCL JCXZ LOOP SETCC
%token <i> SHIFT SHLRD
%token <i> ONEBYTE TWOBYTE ASCADJ
! %token <i> BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7 STRUCT
! %token ALIGN ARPL
! %token BOUND BSS BSF BSR
%token CALL CALLF COPYRIGHT
! %token DB DD DEC DECB DECD DECW DUP DW ENDS ENTER
%token IN INC INCB INCD INCW INT INCLUDE
%token JMPW JMPB JMPF
! %token LAR LEA LINKCOFF LSL
%token MOV MOVB MOVD MOVW
%token IMUL IMULB IMULD IMULW
%token ORG OUT
! %token POP POPW POPD PUSH PUSHW PUSHB PUSHD
%token RCS_ID RET RETF RETD RETFD
%token STACK START
%token TEST TESTB TESTD TESTW TYPE
***************
*** 204,572 ****
};
struct opcode opcodes[] = {
! "aaa", ONEBYTE, 0x37,
! "aad", ASCADJ, 0xd5,
! "aam", ASCADJ, 0xd4,
! "aas", ONEBYTE, 0x3f,
! "cbw", ONEBYTE, 0x98,
! "cwde", TWOBYTE, 0x6698,
! "clc", ONEBYTE, 0xf8,
! "cld", ONEBYTE, 0xfc,
! "cli", ONEBYTE, 0xfa,
! "clts", TWOBYTE, 0x0f06,
! "cmc", ONEBYTE, 0xf5,
! "cmpsb", ONEBYTE, 0xa6,
! "cmpsw", ONEBYTE, 0xa7,
! "cmpsd", TWOBYTE, 0x66a7,
! "cpuid", TWOBYTE, 0x0fa2,
! "cwd", ONEBYTE, 0x99,
! "cdq", TWOBYTE, 0x6699,
! "daa", ONEBYTE, 0x27,
! "das", ONEBYTE, 0x2f,
! "hlt", ONEBYTE, 0xf4,
! "insb", ONEBYTE, 0x6c,
! "insw", ONEBYTE, 0x6d,
! "insd", TWOBYTE, 0x666d,
! "into", ONEBYTE, 0xce,
! "iret", ONEBYTE, 0xcf,
! "iretd", TWOBYTE, 0x66cf,
! "lahf", ONEBYTE, 0x9f,
! "leave", ONEBYTE, 0xc9,
! "lock", ONEBYTE, 0xf0,
! "lodsb", ONEBYTE, 0xac,
! "lodsw", ONEBYTE, 0xad,
! "lodsd", TWOBYTE, 0x66ad,
! "movsb", ONEBYTE, 0xa4,
! "movsw", ONEBYTE, 0xa5,
! "movsd", TWOBYTE, 0x66a5,
! "nop", ONEBYTE, 0x90,
! "outsb", ONEBYTE, 0x6e,
! "outsw", ONEBYTE, 0x6f,
! "outsd", TWOBYTE, 0x666f,
! "popa", ONEBYTE, 0x61,
! "popad", TWOBYTE, 0x6661,
! "popf", ONEBYTE, 0x9d,
! "popfd", TWOBYTE, 0x669d,
! "pusha", ONEBYTE, 0x60,
! "pushad", TWOBYTE, 0x6660,
! "pushf", ONEBYTE, 0x9c,
! "pushfd", TWOBYTE, 0x669c,
! "rep", ONEBYTE, 0xf3,
! "repe", ONEBYTE, 0xf3,
! "repz", ONEBYTE, 0xf3,
! "repne", ONEBYTE, 0xf2,
! "repnz", ONEBYTE, 0xf2,
! "sahf", ONEBYTE, 0x9e,
! "scasb", ONEBYTE, 0xae,
! "scasw", ONEBYTE, 0xaf,
! "scasd", TWOBYTE, 0x66af,
! "stc", ONEBYTE, 0xf9,
! "std", ONEBYTE, 0xfd,
! "sti", ONEBYTE, 0xfb,
! "stosb", ONEBYTE, 0xaa,
! "stosw", ONEBYTE, 0xab,
! "stosd", TWOBYTE, 0x66ab,
! "wait", ONEBYTE, 0x9b,
! "fwait", ONEBYTE, 0x9b,
! "xlat", ONEBYTE, 0xd7,
! "xlatb", ONEBYTE, 0xd7,
!
! ".addrsize", ONEBYTE, 0x67,
! ".opsize", ONEBYTE, 0x66,
! ".segcs", ONEBYTE, 0x2e,
! ".segds", ONEBYTE, 0x3e,
! ".seges", ONEBYTE, 0x26,
! ".segss", ONEBYTE, 0x36,
! ".segfs", ONEBYTE, 0x64,
! ".seggs", ONEBYTE, 0x65,
!
! ".align", ALIGN, NO_ATTR,
! ".bss", BSS, NO_ATTR,
! ".copyright", COPYRIGHT, NO_ATTR,
! ".db", DB, NO_ATTR,
! ".dd", DD, NO_ATTR,
! ".dup", DUP, NO_ATTR,
! ".dw", DW, NO_ATTR,
! ".id", RCS_ID, NO_ATTR,
! ".include", INCLUDE, NO_ATTR,
! ".linkcoff", LINKCOFF, NO_ATTR,
! ".org", ORG, NO_ATTR,
! ".stack", STACK, NO_ATTR,
! ".start", START, NO_ATTR,
! ".type", TYPE, NO_ATTR,
!
! "adc", ARITH2, 2,
! "adcb", ARITH2B, 2,
! "adcd", ARITH2D, 2,
! "adcw", ARITH2W, 2,
! "add", ARITH2, 0,
! "addb", ARITH2B, 0,
! "addd", ARITH2D, 0,
! "addw", ARITH2W, 0,
! "and", ARITH2, 4,
! "andb", ARITH2B, 4,
! "andd", ARITH2D, 4,
! "andw", ARITH2W, 4,
! "bt", BITTEST, 4,
! "btc", BITTEST, 7,
! "btr", BITTEST, 6,
! "bts", BITTEST, 5,
! "call", CALL, NO_ATTR,
! "callf", CALLF, NO_ATTR,
! "cmp", ARITH2, 7,
! "cmpb", ARITH2B, 7,
! "cmpd", ARITH2D, 7,
! "cmpw", ARITH2W, 7,
! "dec", DEC, NO_ATTR,
! "decb", DECB, NO_ATTR,
! "decd", DECD, NO_ATTR,
! "decw", DECW, NO_ATTR,
! "div", GROUP3, 6,
! "divb", GROUP3B, 6,
! "divd", GROUP3D, 6,
! "divw", GROUP3W, 6,
! "idiv", GROUP3, 7,
! "idivb", GROUP3B, 7,
! "idivd", GROUP3D, 7,
! "idivw", GROUP3W, 7,
! "imul", IMUL, NO_ATTR,
! "imulb", IMULB, NO_ATTR,
! "imuld", IMULD, NO_ATTR,
! "imulw", IMULW, NO_ATTR,
! "in", IN, NO_ATTR,
! "inc", INC, NO_ATTR,
! "incb", INCB, NO_ATTR,
! "incd", INCD, NO_ATTR,
! "incw", INCW, NO_ATTR,
! "int", INT, NO_ATTR,
!
! "jo", JCC, 0,
! "jno", JCC, 1,
! "jb", JCC, 2,
! "jc", JCC, 2,
! "jnae", JCC, 2,
! "jnb", JCC, 3,
! "jnc", JCC, 3,
! "jae", JCC, 3,
! "jz", JCC, 4,
! "je", JCC, 4,
! "jnz", JCC, 5,
! "jne", JCC, 5,
! "jbe", JCC, 6,
! "jna", JCC, 6,
! "jnbe", JCC, 7,
! "ja", JCC, 7,
! "js", JCC, 8,
! "jns", JCC, 9,
! "jp", JCC, 10,
! "jpe", JCC, 10,
! "jnp", JCC, 11,
! "jpo", JCC, 11,
! "jl", JCC, 12,
! "jnge", JCC, 12,
! "jnl", JCC, 13,
! "jge", JCC, 13,
! "jle", JCC, 14,
! "jng", JCC, 14,
! "jnle", JCC, 15,
! "jg", JCC, 15,
!
! "jol", JCCL, 0,
! "jnol", JCCL, 1,
! "jbl", JCCL, 2,
! "jcl", JCCL, 2,
! "jnael", JCCL, 2,
! "jnbl", JCCL, 3,
! "jncl", JCCL, 3,
! "jael", JCCL, 3,
! "jzl", JCCL, 4,
! "jel", JCCL, 4,
! "jnzl", JCCL, 5,
! "jnel", JCCL, 5,
! "jbel", JCCL, 6,
! "jnal", JCCL, 6,
! "jnbel", JCCL, 7,
! "jal", JCCL, 7,
! "jsl", JCCL, 8,
! "jnsl", JCCL, 9,
! "jpl", JCCL, 10,
! "jpel", JCCL, 10,
! "jnpl", JCCL, 11,
! "jpol", JCCL, 11,
! "jll", JCCL, 12,
! "jngel", JCCL, 12,
! "jnll", JCCL, 13,
! "jgel", JCCL, 13,
! "jlel", JCCL, 14,
! "jngl", JCCL, 14,
! "jnlel", JCCL, 15,
! "jgl", JCCL, 15,
!
! "jcxz", JCXZ, 0,
! "jecxz", JCXZ, 1,
!
! "jmp", JMPB, NO_ATTR,
! "jmpf", JMPF, NO_ATTR,
! "jmpl", JMPW, NO_ATTR,
! "lds", LXS, 0xc5,
! "les", LXS, 0xc4,
! "lfs", LXS, 0x0fb4,
! "lgs", LXS, 0x0fb5,
! "lss", LXS, 0x0fb2,
! "lgdt", GROUP7, 2,
! "lidt", GROUP7, 3,
! "lldt", GROUP6, 2,
! "lmsw", GROUP7, 6,
! "loop", LOOP, 0xe2,
! "loope", LOOP, 0xe1,
! "loopne", LOOP, 0xe0,
! "loopnz", LOOP, 0xe0,
! "loopz", LOOP, 0xe1,
! "ltr", GROUP6, 3,
! "mov", MOV, NO_ATTR,
! "movb", MOVB, NO_ATTR,
! "movd", MOVD, NO_ATTR,
! "movw", MOVW, NO_ATTR,
! "movsx", MOVSZX, 0xbe,
! "movzx", MOVSZX, 0xb6,
! "mul", GROUP3, 4,
! "mulb", GROUP3B, 4,
! "muld", GROUP3D, 4,
! "mulw", GROUP3W, 4,
! "not", GROUP3, 2,
! "neg", GROUP3, 3,
! "or", ARITH2, 1,
! "orb", ARITH2B, 1,
! "ord", ARITH2D, 1,
! "orw", ARITH2W, 1,
! "out", OUT, NO_ATTR,
! "pop", POP, NO_ATTR,
! "popw", POPW, NO_ATTR,
! "popd", POPD, NO_ATTR,
! "push", PUSH, NO_ATTR,
! "pushw", PUSHW, NO_ATTR,
! "pushd", PUSHD, NO_ATTR,
! "rcl", SHIFT, 2,
! "rcr", SHIFT, 3,
! "ret", RET, NO_ATTR,
! "retd", RETD, NO_ATTR,
! "retf", RETF, NO_ATTR,
! "retfd", RETFD, NO_ATTR,
! "rol", SHIFT, 0,
! "ror", SHIFT, 1,
! "sar", SHIFT, 7,
! "sbb", ARITH2, 3,
! "sbbb", ARITH2B, 3,
! "sbbd", ARITH2D, 3,
! "sbbw", ARITH2W, 3,
!
! "seto", SETCC, 0,
! "setno", SETCC, 1,
! "setb", SETCC, 2,
! "setc", SETCC, 2,
! "setnae", SETCC, 2,
! "setnb", SETCC, 3,
! "setnc", SETCC, 3,
! "setae", SETCC, 3,
! "setz", SETCC, 4,
! "sete", SETCC, 4,
! "setnz", SETCC, 5,
! "setne", SETCC, 5,
! "setbe", SETCC, 6,
! "setna", SETCC, 6,
! "setnbe", SETCC, 7,
! "seta", SETCC, 7,
! "sets", SETCC, 8,
! "setns", SETCC, 9,
! "setp", SETCC, 10,
! "setpe", SETCC, 10,
! "setnp", SETCC, 11,
! "setpo", SETCC, 11,
! "setl", SETCC, 12,
! "setnge", SETCC, 12,
! "setnl", SETCC, 13,
! "setge", SETCC, 13,
! "setle", SETCC, 14,
! "setng", SETCC, 14,
! "setnle", SETCC, 15,
! "setg", SETCC, 15,
!
! "sgdt", GROUP7, 0,
! "sidt", GROUP7, 1,
! "sldt", GROUP6, 0,
! "sal", SHIFT, 4,
! "shl", SHIFT, 4,
! "shld", SHLRD, 0xa4,
! "shr", SHIFT, 5,
! "shrd", SHLRD, 0xac,
! "smsw", GROUP7, 4,
! "str", GROUP6, 1,
! "sub", ARITH2, 5,
! "subb", ARITH2B, 5,
! "subd", ARITH2D, 5,
! "subw", ARITH2W, 5,
! "test", TEST, NO_ATTR,
! "testb", TESTB, NO_ATTR,
! "testw", TESTW, NO_ATTR,
! "testd", TESTD, NO_ATTR,
! "verr", GROUP6, 4,
! "verw", GROUP6, 5,
! "xchg", XCHG, NO_ATTR,
! "xor", ARITH2, 6,
! "xorb", ARITH2B, 6,
! "xord", ARITH2D, 6,
! "xorw", ARITH2W, 6,
!
! "al", REG8, 0,
! "cl", REG8, 1,
! "dl", REG8, 2,
! "bl", REG8, 3,
! "ah", REG8, 4,
! "ch", REG8, 5,
! "dh", REG8, 6,
! "bh", REG8, 7,
!
! "es", SREG, 0,
! "cs", SREG, 1,
! "ss", SREG, 2,
! "ds", SREG, 3,
! "fs", SREG, 4,
! "gs", SREG, 5,
!
! "ax", REG16, 0,
! "cx", REG16, 1,
! "dx", REG16, 2,
! "bx", REG16, 3,
! "sp", REG16, 4,
! "bp", REG16, 5,
! "si", REG16, 6,
! "di", REG16, 7,
!
! "eax", REG32, 0,
! "ecx", REG32, 1,
! "edx", REG32, 2,
! "ebx", REG32, 3,
! "esp", REG32, 4,
! "ebp", REG32, 5,
! "esi", REG32, 6,
! "edi", REG32, 7,
!
! "cr0", CRREG, 0,
! "cr2", CRREG, 2,
! "cr3", CRREG, 3,
!
! "dr0", DRREG, 0,
! "dr1", DRREG, 1,
! "dr2", DRREG, 2,
! "dr3", DRREG, 3,
! "dr6", DRREG, 6,
! "dr7", DRREG, 7,
!
! "tr3", TRREG, 3,
! "tr4", TRREG, 4,
! "tr5", TRREG, 5,
! "tr6", TRREG, 6,
! "tr7", TRREG, 7};
%}
%start lines
--- 230,611 ----
};
struct opcode opcodes[] = {
! {"aaa", ONEBYTE, 0x37},
! {"aad", ASCADJ, 0xd5},
! {"aam", ASCADJ, 0xd4},
! {"aas", ONEBYTE, 0x3f},
! {"cbw", ONEBYTE, 0x98},
! {"cwde", TWOBYTE, 0x6698},
! {"clc", ONEBYTE, 0xf8},
! {"cld", ONEBYTE, 0xfc},
! {"cli", ONEBYTE, 0xfa},
! {"clts", TWOBYTE, 0x0f06},
! {"cmc", ONEBYTE, 0xf5},
! {"cmpsb", ONEBYTE, 0xa6},
! {"cmpsw", ONEBYTE, 0xa7},
! {"cmpsd", TWOBYTE, 0x66a7},
! {"cpuid", TWOBYTE, 0x0fa2},
! {"cwd", ONEBYTE, 0x99},
! {"cdq", TWOBYTE, 0x6699},
! {"daa", ONEBYTE, 0x27},
! {"das", ONEBYTE, 0x2f},
! {"hlt", ONEBYTE, 0xf4},
! {"insb", ONEBYTE, 0x6c},
! {"insw", ONEBYTE, 0x6d},
! {"insd", TWOBYTE, 0x666d},
! {"into", ONEBYTE, 0xce},
! {"iret", ONEBYTE, 0xcf},
! {"iretd", TWOBYTE, 0x66cf},
! {"lahf", ONEBYTE, 0x9f},
! {"leave", ONEBYTE, 0xc9},
! {"lock", ONEBYTE, 0xf0},
! {"lodsb", ONEBYTE, 0xac},
! {"lodsw", ONEBYTE, 0xad},
! {"lodsd", TWOBYTE, 0x66ad},
! {"movsb", ONEBYTE, 0xa4},
! {"movsw", ONEBYTE, 0xa5},
! {"movsd", TWOBYTE, 0x66a5},
! {"nop", ONEBYTE, 0x90},
! {"outsb", ONEBYTE, 0x6e},
! {"outsw", ONEBYTE, 0x6f},
! {"outsd", TWOBYTE, 0x666f},
! {"popa", ONEBYTE, 0x61},
! {"popad", TWOBYTE, 0x6661},
! {"popf", ONEBYTE, 0x9d},
! {"popfd", TWOBYTE, 0x669d},
! {"pusha", ONEBYTE, 0x60},
! {"pushad", TWOBYTE, 0x6660},
! {"pushf", ONEBYTE, 0x9c},
! {"pushfd", TWOBYTE, 0x669c},
! {"rep", ONEBYTE, 0xf3},
! {"repe", ONEBYTE, 0xf3},
! {"repz", ONEBYTE, 0xf3},
! {"repne", ONEBYTE, 0xf2},
! {"repnz", ONEBYTE, 0xf2},
! {"sahf", ONEBYTE, 0x9e},
! {"scasb", ONEBYTE, 0xae},
! {"scasw", ONEBYTE, 0xaf},
! {"scasd", TWOBYTE, 0x66af},
! {"stc", ONEBYTE, 0xf9},
! {"std", ONEBYTE, 0xfd},
! {"sti", ONEBYTE, 0xfb},
! {"stosb", ONEBYTE, 0xaa},
! {"stosw", ONEBYTE, 0xab},
! {"stosd", TWOBYTE, 0x66ab},
! {"wait", ONEBYTE, 0x9b},
! {"fwait", ONEBYTE, 0x9b},
! {"xlat", ONEBYTE, 0xd7},
! {"xlatb", ONEBYTE, 0xd7},
!
! {".addrsize", ONEBYTE, 0x67},
! {".opsize", ONEBYTE, 0x66},
! {".segcs", ONEBYTE, 0x2e},
! {".segds", ONEBYTE, 0x3e},
! {".seges", ONEBYTE, 0x26},
! {".segss", ONEBYTE, 0x36},
! {".segfs", ONEBYTE, 0x64},
! {".seggs", ONEBYTE, 0x65},
!
! {".align", ALIGN, NO_ATTR},
! {".bss", BSS, NO_ATTR},
! {".copyright", COPYRIGHT, NO_ATTR},
! {".db", DB, NO_ATTR},
! {".dd", DD, NO_ATTR},
! {".dup", DUP, NO_ATTR},
! {".dw", DW, NO_ATTR},
! {".ends",ENDS, NO_ATTR},
! {".id", RCS_ID, NO_ATTR},
! {".include", INCLUDE, NO_ATTR},
! {".linkcoff", LINKCOFF, NO_ATTR},
! {".org", ORG, NO_ATTR},
! {".stack", STACK, NO_ATTR},
! {".start", START, NO_ATTR},
! {".struct", STRUCT, 's'},
! {".type", TYPE, NO_ATTR},
! {".union", STRUCT, 'u'},
!
! {"adc", ARITH2, 2},
! {"adcb", ARITH2B, 2},
! {"adcd", ARITH2D, 2},
! {"adcw", ARITH2W, 2},
! {"add", ARITH2, 0},
! {"addb", ARITH2B, 0},
! {"addd", ARITH2D, 0},
! {"addw", ARITH2W, 0},
! {"and", ARITH2, 4},
! {"andb", ARITH2B, 4},
! {"andd", ARITH2D, 4},
! {"andw", ARITH2W, 4},
! {"arpl", ARPL, NO_ATTR},
! {"bound", BOUND, NO_ATTR},
! {"bsf", BSF, NO_ATTR},
! {"bsr", BSR, NO_ATTR},
! {"bt", BITTEST, 4},
! {"btc", BITTEST, 7},
! {"btr", BITTEST, 6},
! {"bts", BITTEST, 5},
! {"call", CALL, NO_ATTR},
! {"callf", CALLF, NO_ATTR},
! {"cmp", ARITH2, 7},
! {"cmpb", ARITH2B, 7},
! {"cmpd", ARITH2D, 7},
! {"cmpw", ARITH2W, 7},
! {"dec", DEC, NO_ATTR},
! {"decb", DECB, NO_ATTR},
! {"decd", DECD, NO_ATTR},
! {"decw", DECW, NO_ATTR},
! {"div", GROUP3, 6},
! {"divb", GROUP3B, 6},
! {"divd", GROUP3D, 6},
! {"divw", GROUP3W, 6},
! {"enter", ENTER, NO_ATTR},
! {"idiv", GROUP3, 7},
! {"idivb", GROUP3B, 7},
! {"idivd", GROUP3D, 7},
! {"idivw", GROUP3W, 7},
! {"imul", IMUL, NO_ATTR},
! {"imulb", IMULB, NO_ATTR},
! {"imuld", IMULD, NO_ATTR},
! {"imulw", IMULW, NO_ATTR},
! {"in", IN, NO_ATTR},
! {"inc", INC, NO_ATTR},
! {"incb", INCB, NO_ATTR},
! {"incd", INCD, NO_ATTR},
! {"incw", INCW, NO_ATTR},
! {"int", INT, NO_ATTR},
!
! {"jo", JCC, 0},
! {"jno", JCC, 1},
! {"jb", JCC, 2},
! {"jc", JCC, 2},
! {"jnae", JCC, 2},
! {"jnb", JCC, 3},
! {"jnc", JCC, 3},
! {"jae", JCC, 3},
! {"jz", JCC, 4},
! {"je", JCC, 4},
! {"jnz", JCC, 5},
! {"jne", JCC, 5},
! {"jbe", JCC, 6},
! {"jna", JCC, 6},
! {"jnbe", JCC, 7},
! {"ja", JCC, 7},
! {"js", JCC, 8},
! {"jns", JCC, 9},
! {"jp", JCC, 10},
! {"jpe", JCC, 10},
! {"jnp", JCC, 11},
! {"jpo", JCC, 11},
! {"jl", JCC, 12},
! {"jnge", JCC, 12},
! {"jnl", JCC, 13},
! {"jge", JCC, 13},
! {"jle", JCC, 14},
! {"jng", JCC, 14},
! {"jnle", JCC, 15},
! {"jg", JCC, 15},
!
! {"jol", JCCL, 0},
! {"jnol", JCCL, 1},
! {"jbl", JCCL, 2},
! {"jcl", JCCL, 2},
! {"jnael", JCCL, 2},
! {"jnbl", JCCL, 3},
! {"jncl", JCCL, 3},
! {"jael", JCCL, 3},
! {"jzl", JCCL, 4},
! {"jel", JCCL, 4},
! {"jnzl", JCCL, 5},
! {"jnel", JCCL, 5},
! {"jbel", JCCL, 6},
! {"jnal", JCCL, 6},
! {"jnbel", JCCL, 7},
! {"jal", JCCL, 7},
! {"jsl", JCCL, 8},
! {"jnsl", JCCL, 9},
! {"jpl", JCCL, 10},
! {"jpel", JCCL, 10},
! {"jnpl", JCCL, 11},
! {"jpol", JCCL, 11},
! {"jll", JCCL, 12},
! {"jngel", JCCL, 12},
! {"jnll", JCCL, 13},
! {"jgel", JCCL, 13},
! {"jlel", JCCL, 14},
! {"jngl", JCCL, 14},
! {"jnlel", JCCL, 15},
! {"jgl", JCCL, 15},
!
! {"jcxz", JCXZ, 0},
! {"jecxz", JCXZ, 1},
!
! {"jmp", JMPB, NO_ATTR},
! {"jmpf", JMPF, NO_ATTR},
! {"jmpl", JMPW, NO_ATTR},
! {"lar", LAR, NO_ATTR},
! {"lds", LXS, 0xc5},
! {"lea", LEA, NO_ATTR},
! {"les", LXS, 0xc4},
! {"lfs", LXS, 0x0fb4},
! {"lgs", LXS, 0x0fb5},
! {"lsl", LSL, NO_ATTR},
! {"lss", LXS, 0x0fb2},
! {"lgdt", GROUP7, 2},
! {"lidt", GROUP7, 3},
! {"lldt", GROUP6, 2},
! {"lmsw", GROUP7, 6},
! {"loop", LOOP, 0xe2},
! {"loope", LOOP, 0xe1},
! {"loopne", LOOP, 0xe0},
! {"loopnz", LOOP, 0xe0},
! {"loopz", LOOP, 0xe1},
! {"ltr", GROUP6, 3},
! {"mov", MOV, NO_ATTR},
! {"movb", MOVB, NO_ATTR},
! {"movd", MOVD, NO_ATTR},
! {"movw", MOVW, NO_ATTR},
! {"movsx", MOVSZX, 0xbe},
! {"movzx", MOVSZX, 0xb6},
! {"mul", GROUP3, 4},
! {"mulb", GROUP3B, 4},
! {"muld", GROUP3D, 4},
! {"mulw", GROUP3W, 4},
! {"not", GROUP3, 2},
! {"neg", GROUP3, 3},
! {"or", ARITH2, 1},
! {"orb", ARITH2B, 1},
! {"ord", ARITH2D, 1},
! {"orw", ARITH2W, 1},
! {"out", OUT, NO_ATTR},
! {"pop", POP, NO_ATTR},
! {"popw", POPW, NO_ATTR},
! {"popd", POPD, NO_ATTR},
! {"push", PUSH, NO_ATTR},
! {"pushb", PUSHB, NO_ATTR},
! {"pushw", PUSHW, NO_ATTR},
! {"pushd", PUSHD, NO_ATTR},
! {"rcl", SHIFT, 2},
! {"rcr", SHIFT, 3},
! {"ret", RET, NO_ATTR},
! {"retd", RETD, NO_ATTR},
! {"retf", RETF, NO_ATTR},
! {"retfd", RETFD, NO_ATTR},
! {"rol", SHIFT, 0},
! {"ror", SHIFT, 1},
! {"sar", SHIFT, 7},
! {"sbb", ARITH2, 3},
! {"sbbb", ARITH2B, 3},
! {"sbbd", ARITH2D, 3},
! {"sbbw", ARITH2W, 3},
!
! {"seto", SETCC, 0},
! {"setno", SETCC, 1},
! {"setb", SETCC, 2},
! {"setc", SETCC, 2},
! {"setnae", SETCC, 2},
! {"setnb", SETCC, 3},
! {"setnc", SETCC, 3},
! {"setae", SETCC, 3},
! {"setz", SETCC, 4},
! {"sete", SETCC, 4},
! {"setnz", SETCC, 5},
! {"setne", SETCC, 5},
! {"setbe", SETCC, 6},
! {"setna", SETCC, 6},
! {"setnbe", SETCC, 7},
! {"seta", SETCC, 7},
! {"sets", SETCC, 8},
! {"setns", SETCC, 9},
! {"setp", SETCC, 10},
! {"setpe", SETCC, 10},
! {"setnp", SETCC, 11},
! {"setpo", SETCC, 11},
! {"setl", SETCC, 12},
! {"setnge", SETCC, 12},
! {"setnl", SETCC, 13},
! {"setge", SETCC, 13},
! {"setle", SETCC, 14},
! {"setng", SETCC, 14},
! {"setnle", SETCC, 15},
! {"setg", SETCC, 15},
!
! {"sgdt", GROUP7, 0},
! {"sidt", GROUP7, 1},
! {"sldt", GROUP6, 0},
! {"sal", SHIFT, 4},
! {"shl", SHIFT, 4},
! {"shld", SHLRD, 0xa4},
! {"shr", SHIFT, 5},
! {"shrd", SHLRD, 0xac},
! {"smsw", GROUP7, 4},
! {"str", GROUP6, 1},
! {"sub", ARITH2, 5},
! {"subb", ARITH2B, 5},
! {"subd", ARITH2D, 5},
! {"subw", ARITH2W, 5},
! {"test", TEST, NO_ATTR},
! {"testb", TESTB, NO_ATTR},
! {"testw", TESTW, NO_ATTR},
! {"testd", TESTD, NO_ATTR},
! {"verr", GROUP6, 4},
! {"verw", GROUP6, 5},
! {"xchg", XCHG, NO_ATTR},
! {"xor", ARITH2, 6},
! {"xorb", ARITH2B, 6},
! {"xord", ARITH2D, 6},
! {"xorw", ARITH2W, 6},
!
! {"al", REG8, 0},
! {"cl", REG8, 1},
! {"dl", REG8, 2},
! {"bl", REG8, 3},
! {"ah", REG8, 4},
! {"ch", REG8, 5},
! {"dh", REG8, 6},
! {"bh", REG8, 7},
!
! {"es", SREG, 0},
! {"cs", SREG, 1},
! {"ss", SREG, 2},
! {"ds", SREG, 3},
! {"fs", SREG, 4},
! {"gs", SREG, 5},
!
! {"ax", REG16, 0},
! {"cx", REG16, 1},
! {"dx", REG16, 2},
! {"bx", REG16, 3},
! {"sp", REG16, 4},
! {"bp", REG16, 5},
! {"si", REG16, 6},
! {"di", REG16, 7},
!
! {"eax", REG32, 0},
! {"ecx", REG32, 1},
! {"edx", REG32, 2},
! {"ebx", REG32, 3},
! {"esp", REG32, 4},
! {"ebp", REG32, 5},
! {"esi", REG32, 6},
! {"edi", REG32, 7},
!
! {"cr0", CRREG, 0},
! {"cr2", CRREG, 2},
! {"cr3", CRREG, 3},
!
! {"dr0", DRREG, 0},
! {"dr1", DRREG, 1},
! {"dr2", DRREG, 2},
! {"dr3", DRREG, 3},
! {"dr6", DRREG, 6},
! {"dr7", DRREG, 7},
!
! {"tr3", TRREG, 3},
! {"tr4", TRREG, 4},
! {"tr5", TRREG, 5},
! {"tr6", TRREG, 6},
! {"tr7", TRREG, 7},
! };
%}
%start lines
***************
*** 586,591 ****
--- 625,644 ----
| ID ':' { set_symbol($1, pc)->type |= (pc?SYM_data:SYM_code); }
| ID '=' const { set_symbol($1, $3)->type = SYM_abs; }
| ID '=' PC offset { set_symbol($1, pc + $4)->type = SYM_abs; }
+ | ID '=' const '-' PC { set_symbol($1, $3 - pc)->type = SYM_abs; }
+ | STRUCT ID '\n' { struct_pc=0;
+ struct_tp=$1;
+ struct_sym=$2->name;
+ lineno++;
+ $<sym>$=symtab;
+ symtab=symtab->next;
+ }
+ struct_lines
+ ENDS { set_symbol($2, struct_pc)->type = SYM_abs;
+ $<sym>4->next=symtab;
+ symtab=$<sym>4;
+ }
+ | ID STRUCT ID { emit_struct($1,$2,$3); }
| error
| ONEBYTE { emitb($1); }
***************
*** 607,617 ****
| ARITH2 REG8 ',' regmem { emitb($1*8+2); reg($2); }
| ARITH2W regmem ',' constID { emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); }
! | ARITH2 REG16 ',' constID { if ($2)
! {emitb(0x81); modrm(3, $1, $2);}
! else
modrm (0,$1,5);
! emits($4.sym,$4.ofs,REL_abs);
}
| ARITH2 REG16 ',' REG16 { emitb($1*8+1); modrm(3, $4, $2); }
| ARITH2 regmem ',' REG16 { emitb($1*8+1); reg($4); }
--- 660,678 ----
| ARITH2 REG8 ',' regmem { emitb($1*8+2); reg($2); }
| ARITH2W regmem ',' constID { emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); }
! | ARITH2 REG16 ',' constID { if ($2) {
! int v=$4.ofs+$4.sym->value;
! if ($4.sym->defined && v>=-128 && v<=127) {
! emitb(0x83); modrm(3, $1, $2);
! emits($4.sym,$4.ofs,REL_abs8);
! } else {
! emitb(0x81); modrm(3, $1, $2);
! emits($4.sym,$4.ofs,REL_abs);
! }
! } else {
modrm (0,$1,5);
! emits($4.sym,$4.ofs,REL_abs);
! }
}
| ARITH2 REG16 ',' REG16 { emitb($1*8+1); modrm(3, $4, $2); }
| ARITH2 regmem ',' REG16 { emitb($1*8+1); reg($4); }
***************
*** 619,639 ****
| ARITH2D regmem ',' constID { emitb(0x66); emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); emitw($4.ofs >> 16); }
| ARITH2 REG32 ',' constID { emitb(0x66);
! if ($2)
! {emitb(0x81); modrm(3, $1, $2);}
! else
modrm (0,$1,5);
! emits($4.sym,$4.ofs,REL_abs); emitw($4.ofs >> 16); }
| ARITH2 REG32 ',' REG32 { emitb(0x66); emitb($1*8+1); modrm(3, $4, $2); }
| ARITH2 regmem ',' REG32 { emitb(0x66); emitb($1*8+1); reg($4); }
| ARITH2 REG32 ',' regmem { emitb(0x66); emitb($1*8+3); reg($2); }
| ASCADJ { emitb($1); emitb(0x0a); }
| ASCADJ const { emitb($1); emitb($2); }
| ALIGN const { do_align($2,0x90); }
| ALIGN const ',' const { do_align($2,$4); }
| BITTEST REG16 ',' REG16 { emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
| BITTEST regmem ',' REG16 { emitb(0x0f); emitb($1*8+0x83); reg($4); }
| BITTEST REG32 ',' REG32 { emitb(0x66); emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
--- 680,715 ----
| ARITH2D regmem ',' constID { emitb(0x66); emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); emitw($4.ofs >> 16); }
| ARITH2 REG32 ',' constID { emitb(0x66);
! if ($2) {
! int v=$4.ofs+$4.sym->value;
! if ($4.sym->defined && v>=-128 && v<=127) {
! emitb(0x83); modrm(3, $1, $2);
! emits($4.sym,$4.ofs,REL_abs8);
! } else {
! emitb(0x81); modrm(3, $1, $2);
! emits($4.sym,$4.ofs,REL_abs32);
! }
! } else {
modrm (0,$1,5);
! emits($4.sym,$4.ofs,REL_abs32);
! }
! }
| ARITH2 REG32 ',' REG32 { emitb(0x66); emitb($1*8+1); modrm(3, $4, $2); }
| ARITH2 regmem ',' REG32 { emitb(0x66); emitb($1*8+1); reg($4); }
| ARITH2 REG32 ',' regmem { emitb(0x66); emitb($1*8+3); reg($2); }
+ | ARPL REG16 ',' REG16 { emitb(0x63); modrm(3,$4,$2); }
+ | ARPL regmem ',' REG16 { emitb(0x63); reg($4); }
+
| ASCADJ { emitb($1); emitb(0x0a); }
| ASCADJ const { emitb($1); emitb($2); }
| ALIGN const { do_align($2,0x90); }
| ALIGN const ',' const { do_align($2,$4); }
+ | BOUND REG16 ',' regmem { emitb(0x62); reg($2); }
+ | BOUND REG32 ',' regmem { emitb(0x66); emitb(0x62); reg($2); }
+
| BITTEST REG16 ',' REG16 { emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
| BITTEST regmem ',' REG16 { emitb(0x0f); emitb($1*8+0x83); reg($4); }
| BITTEST REG32 ',' REG32 { emitb(0x66); emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
***************
*** 642,649 ****
--- 718,736 ----
| BITTEST regmem ',' const { emitb(0x0f); emitb(0xba); reg($1); emitb($4); }
| BITTEST REG32 ',' const { emitb(0x66); emitb(0x0f); emitb(0xba); modrm(3, $1, $2); emitb($4); }
+ | BSF REG16 ',' REG16 { emitb(0x0f); emitb(0xbc); modrm(3, $4, $2); }
+ | BSF REG16 ',' regmem { emitb(0x0f); emitb(0xbc); reg($2); }
+ | BSF REG32 ',' REG32 { emitb(0x66); emitb(0x0f); emitb(0xbc); modrm(3, $4, $2); }
+ | BSF REG32 ',' regmem { emitb(0x66); emitb(0x0f); emitb(0xbc); reg($2); }
+
+ | BSR REG16 ',' REG16 { emitb(0x0f); emitb(0xbd); modrm(3, $4, $2); }
+ | BSR REG16 ',' regmem { emitb(0x0f); emitb(0xbd); reg($2); }
+ | BSR REG32 ',' REG32 { emitb(0x66); emitb(0x0f); emitb(0xbd); modrm(3, $4, $2); }
+ | BSR REG32 ',' regmem { emitb(0x66); emitb(0x0f); emitb(0xbd); reg($2); }
+
| CALL ID { emitb(0xe8); emits($2,0,REL_16); $2->type |= SYM_code; }
| CALLF regmem { emitb(0xff); reg(3); }
+ | CALLF const ':' constID { emitb(0x9a); emits($4.sym,$4.ofs,REL_abs); emitw($2); }
| COPYRIGHT STRING { strbuf[strbuflen] = 0; add_copyright(strbuf); }
| RCS_ID { strbuf[strbuflen] = 0; add_rcs_ident(strbuf); }
***************
*** 659,664 ****
--- 746,753 ----
| DECW regmem { emitb(0xff); reg(1); }
| DECD regmem { emitb(0x66); emitb(0xff); reg(1); }
+ | ENTER const ',' const { emitb(0xc8); emitw($2); emitb($4); }
+
| IN REG8 ',' const { emitb(0xe4); emitb($4); }
| IN REG16 ',' const { emitb(0xe5); emitb($4); }
| IN REG32 ',' const { emitb(0x66); emitb(0xe5); emitb($4);}
***************
*** 729,737 ****
--- 818,835 ----
| JMPF regmem { emitb(0xff); reg(5); }
| JMPF const ':' constID { emitb(0xea); emits($4.sym,$4.ofs,REL_abs); emitw($2); }
+ | LAR REG16 ',' REG16 { emitb(0x0f); emitb(0x02); modrm(3, $4, $2); }
+ | LAR REG16 ',' regmem { emitb(0x0f); emitb(0x02); reg($2); }
+
+ | LEA REG16 ',' regmem { emitb(0x8d); reg($2); }
+ | LEA REG32 ',' regmem { emitb(0x66); emitb(0x8d); reg($2); }
+
| LINKCOFF STRING { strbuf[strbuflen]=0; do_linkcoff(strbuf); }
| LOOP ID { emitb($1); emits($2,0,REL_8); }
+ | LSL REG16 ',' REG16 { emitb(0x0f); emitb(0x03); modrm(3, $4, $2); }
+ | LSL REG16 ',' regmem { emitb(0x0f); emitb(0x03); reg($2); }
+
| LXS REG16 ',' regmem { if ($1>>8) emitb($1>>8); emitb($1 & 0xff); reg($2); }
| LXS REG32 ',' regmem { emitb(0x66); if ($1>>8) emitb($1>>8); emitb($1 & 0xff); reg($2); }
***************
*** 818,823 ****
--- 916,922 ----
| PUSH SREG { do_sreg_push($2); }
| PUSHW regmem { emitb(0xff); reg(6); }
| PUSHD regmem { emitb(0x66); emitb(0xff); reg(6); }
+ | PUSHB const { emitb(0x6a); emitb($2); }
| PUSHW constID { emitb(0x68); emits($2.sym,$2.ofs,REL_abs); }
| PUSHD constID { emitb(0x66); emitb(0x68); emits($2.sym,$2.ofs,REL_abs); emitw($2.ofs >> 16); }
***************
*** 890,895 ****
--- 989,1048 ----
| XCHG regmem ',' REG32 { emitb(0x66); emitb(0x87); reg($4); }
;
+ struct_lines
+ :
+ | struct_lines struct_line '\n' { lineno++; }
+ ;
+
+ struct_line
+ :
+ | ID ':' { add_struct_element($1); }
+ | ID STRUCT ID { build_struct($1,$2,$3); }
+ | struct_db
+ | ID { add_struct_element($1); }
+ struct_db
+ ;
+
+ struct_db
+ : DB { if (struct_tp=='s') {
+ struct_pc++;
+ } else {
+ struct_pc=MAX(struct_pc,1);
+ }
+ }
+ | DB const DUP { if (struct_tp=='s') {
+ struct_pc+=$2;
+ } else {
+ struct_pc=MAX(struct_pc,$2);
+ }
+ }
+ | DW { if (struct_tp=='s') {
+ struct_pc+=2;
+ } else {
+ struct_pc=MAX(struct_pc,2);
+ }
+ }
+ | DW const DUP { if (struct_tp=='s') {
+ struct_pc+=2*$2;
+ } else {
+ struct_pc=MAX(struct_pc,2*$2);
+ }
+ }
+ | DD { if (struct_tp=='s') {
+ struct_pc+=4;
+ } else {
+ struct_pc=MAX(struct_pc,4);
+ }
+ }
+ | DD const DUP { if (struct_tp=='s') {
+ struct_pc+=4*$2;
+ } else {
+ struct_pc=MAX(struct_pc,4*$2);
+ }
+ }
+ ;
+
+
dbitem
: const { emitb($1); }
| STRING { emit(strbuf, strbuflen); }
***************
*** 937,947 ****
regmemitem
: SREG ':' regmemitem { emitb(sreg_overrides[$1]); }
! | REG16 { _modrm.regs |= (1<<$1); }
| UID { _modrm.syms[_modrm.nsyms++] = $1; }
| const { _modrm.offset += $1; }
;
const
: NUMBER { $$ = $1; }
| KID { $$ = $1->value; }
--- 1090,1133 ----
regmemitem
: SREG ':' regmemitem { emitb(sreg_overrides[$1]); }
! | REG16 { if (_modrm.addr32) {
! _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
! yyerror("Cannot mix 16 and 32 bit addressing");
! } else {
! _modrm.regs |= (1<<$1);
! _modrm.addr16=1;
! }
! }
! | REG32 { addr32((1<<$1)|0x100); }
! | scaledindex { addr32($1); }
| UID { _modrm.syms[_modrm.nsyms++] = $1; }
| const { _modrm.offset += $1; }
;
+ scaledindex
+ : REG32 '*' const { if ($3==1 || $3==2 || $3==4 || $3==8)
+ $$ = (1<<($1)) | ($3<<8);
+ else {
+ _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ yyerror("Scale must be 1,2,4 or 8");
+ }
+ }
+ | const '*' REG32 { if ($1==1 || $1==2 || $1==4 || $1==8)
+ $$ = (1<<($3)) | ($1<<8);
+ else {
+ _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ yyerror("Scale must be 1,2,4 or 8");
+ }
+ }
+ | REG32 OP_SHL const { if ($3>=0 && $3<=3)
+ $$ = (1<<($1)) | (0x100<<$3);
+ else {
+ _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ yyerror("Shift must be 0,1,2 or 3");
+ }
+ }
+ ;
+
const
: NUMBER { $$ = $1; }
| KID { $$ = $1->value; }
***************
*** 1014,1025 ****
return strcmp (((struct opcode *)e1)->name, ((struct opcode *)e2)->name);
}
! main(int argc, char **argv)
{
Symbol *s;
Patch *p;
unsigned char exe[EXE_HEADER_SIZE+4];
- int undefs=0;
int symcount = 0;
int min_uninit;
time_t now;
--- 1200,1210 ----
return strcmp (((struct opcode *)e1)->name, ((struct opcode *)e2)->name);
}
! int main(int argc, char **argv)
{
Symbol *s;
Patch *p;
unsigned char exe[EXE_HEADER_SIZE+4];
int symcount = 0;
int min_uninit;
time_t now;
***************
*** 1034,1040 ****
if (argc < 2)
{
! printf("usage: djasm infile [outfile] [mapfile]\n");
exit(1);
}
inname = argv[1];
--- 1219,1225 ----
if (argc < 2)
{
! fprintf(stderr,"usage: djasm infile [outfile] [mapfile]\n");
exit(1);
}
inname = argv[1];
***************
*** 1063,1069 ****
{
fprintf(stderr, "Undefined symbol `%s', first used on line %d\n", s->name, s->first_used);
for (p=s->patches; p; p=p->next)
! printf("\treferenced on line %d\n", p->lineno);
undefs++;
}
}
--- 1248,1254 ----
{
fprintf(stderr, "Undefined symbol `%s', first used on line %d\n", s->name, s->first_used);
for (p=s->patches; p; p=p->next)
! fprintf(stderr,"\treferenced on line %d\n", p->lineno);
undefs++;
}
}
***************
*** 1166,1171 ****
--- 1351,1357 ----
case OUT_exe:
case OUT_com:
case OUT_bin:
+ case OUT_sys:
outfile = fopen(outfilename, "wb");
break;
case OUT_h:
***************
*** 1193,1198 ****
--- 1379,1385 ----
break;
case OUT_bin:
+ case OUT_sys:
fwrite(outbin, bsspc, 1, outfile);
break;
***************
*** 1222,1248 ****
leader = INC_LEADER;
else
leader = S_LEADER;
if (image_type == OUT_exe)
for (i=0; i<EXE_HEADER_SIZE; i++)
{
- if ((i%15) == 0)
- fputs(leader, outfile);
fprintf(outfile, "0x%02x", exe[i]);
if ((i&15) == 15)
{
fputc('\n', outfile);
}
else
fputc(',', outfile);
}
for (i=((image_type==OUT_com)?0x100:0); i<bsspc; i++)
{
- if ((i&15) == 0)
- fputs(leader, outfile);
fprintf(outfile, "0x%02x", outbin[i]);
if ((i&15) == 15)
{
fputc('\n', outfile);
}
else
if (i<bsspc-1)
--- 1409,1434 ----
leader = INC_LEADER;
else
leader = S_LEADER;
+ fputs(leader, outfile);
if (image_type == OUT_exe)
for (i=0; i<EXE_HEADER_SIZE; i++)
{
fprintf(outfile, "0x%02x", exe[i]);
if ((i&15) == 15)
{
fputc('\n', outfile);
+ fputs(leader, outfile);
}
else
fputc(',', outfile);
}
for (i=((image_type==OUT_com)?0x100:0); i<bsspc; i++)
{
fprintf(outfile, "0x%02x", outbin[i]);
if ((i&15) == 15)
{
fputc('\n', outfile);
+ fputs(leader, outfile);
}
else
if (i<bsspc-1)
***************
*** 1284,1296 ****
fputc('\n', mapfile);
fclose(mapfile);
}
}
void yyerror(char *s)
{
fprintf(stderr, "%s:%d: %s\n", inname, lineno, s);
strbuf[strbuflen] = 0;
! fprintf(stderr, "Last token was `%s' (%s)\n", last_token, yytname[yytranslate[last_tret]]);
total_errors++;
}
--- 1470,1483 ----
fputc('\n', mapfile);
fclose(mapfile);
}
+ return 0;
}
void yyerror(char *s)
{
fprintf(stderr, "%s:%d: %s\n", inname, lineno, s);
strbuf[strbuflen] = 0;
! fprintf(stderr, "Last token was `%s' (%s)\n", last_token, yytname[(unsigned char)yytranslate[last_tret]]);
total_errors++;
}
***************
*** 1315,1331 ****
return s;
}
Symbol *set_symbol(Symbol *s, int value)
{
if (istemp(s->name, 'b'))
s->defined = 0;
if (s->defined)
! printf("Warning: symbol %s redefined\n", s->name);
s->value = value;
s->defined = 1;
while (s->patches)
{
! int v, o;
unsigned char *cp;
Patch *p = s->patches;
s->patches = s->patches->next;
--- 1502,1620 ----
return s;
}
+ void add_struct_element(Symbol *s)
+ {
+ if (islocal(s->name) || istemp(s->name,0)) {
+ yyerror("Cannot have local or temporary labels within a structure");
+ } else {
+ char *id=alloca(strlen(s->name)+strlen(struct_sym)+2);
+ strcpy(id,struct_sym);
+ strcat(id,".");
+ strcat(id,s->name);
+ if (!s->defined && !s->patches) {
+ /* only delete fresh symbols */
+ destroy_symbol(s,0);
+ }
+ if (struct_tp=='s') {
+ /* .struct */
+ set_symbol(get_symbol(id,1),struct_pc);
+ } else {
+ /* .union */
+ set_symbol(get_symbol(id,1),0);
+ }
+ }
+ }
+
+ int is_structure(Symbol *s)
+ {
+ char *n=s->name;
+ size_t l=strlen(n);
+ if (!s->next) {
+ /* the elements of a struct or union always follow the symbol */
+ return 0;
+ }
+ s=s->next;
+ if (strncmp(n,s->name,l) || s->name[l]!='.') {
+ /* Structure elements always have the structure name followed by a period before
+ * the element name.
+ */
+ return 0;
+ }
+ return 1;
+ }
+
+ int set_structure_symbols(Symbol *ele, Symbol *struc, int tp, int base, int type)
+ {
+ if (tp!='s') {
+ yyerror("must use `.struct' to emit structures or unions");
+ return 0;
+ }
+ if (!struc->defined) {
+ yyerror("undefined symbol used in struct");
+ return 0;
+ }
+ if (!is_structure(struc)) {
+ yyerror("symbol must be a .struct or .union");
+ return 0;
+ }
+ set_symbol(ele,base)->type|=type;
+ {
+ int sLen=strlen(struc->name);
+ int eLen=strlen(ele->name);
+ Symbol *s=struc->next;
+ while (s && !strncmp(s->name,struc->name,sLen) && s->name[sLen]=='.') {
+ char *id=alloca(strlen(s->name)-sLen+eLen+1);
+ strcpy(id,ele->name);
+ strcpy(id+eLen,s->name+sLen);
+ set_symbol(get_symbol(id,1),base+s->value)->type|=type;
+ s=s->next;
+ }
+ }
+ return 1;
+ }
+
+ void emit_struct(Symbol *ele, int tp, Symbol *struc)
+ {
+ int i;
+
+ if (set_structure_symbols(ele,struc,tp,pc,(pc?SYM_data:SYM_code)))
+ for (i=0; i<struc->value; i++) emitb(0); /* only unitialized structures supported */
+ }
+
+ void build_struct(Symbol *ele, int tp, Symbol *struc)
+ {
+ if (islocal(ele->name) || istemp(ele->name,0)) {
+ yyerror("Cannot have local or temporary labels within a structure");
+ } else {
+ char *id=alloca(strlen(ele->name)+strlen(struct_sym)+2);
+ strcpy(id,struct_sym);
+ strcat(id,".");
+ strcat(id,ele->name);
+ if (!ele->defined && !ele->patches) {
+ /* only delete fresh symbols */
+ destroy_symbol(ele,0);
+ }
+ set_structure_symbols(get_symbol(id,1),struc,tp,struct_pc,0);
+ if (struct_tp=='s')
+ struct_pc+=struc->value;
+ else
+ struct_pc+=MAX(struct_pc,struc->value);
+ }
+ }
+
Symbol *set_symbol(Symbol *s, int value)
{
+ if (!islocal(s->name) && !istemp(s->name,0))
+ destroy_locals();
if (istemp(s->name, 'b'))
s->defined = 0;
if (s->defined)
! fprintf(stderr,"Warning: symbol %s redefined\n", s->name);
s->value = value;
s->defined = 1;
while (s->patches)
{
! int v=0, o=0;
unsigned char *cp;
Patch *p = s->patches;
s->patches = s->patches->next;
***************
*** 1388,1393 ****
--- 1677,1742 ----
return s;
}
+ void destroy_symbol(Symbol *sym, int undef_error)
+ {
+ Symbol **s=&symtab;
+ while (*s)
+ {
+ if (*s==sym)
+ {
+ Symbol *_s=*s;
+ if (undef_error && !_s->defined && _s->patches)
+ {
+ Patch *p,*_p;
+ fprintf(stderr, "Undefined symbol `%s', first used on line %d\n", _s->name, _s->first_used);
+ for (p=_s->patches; p; p=_p) {
+ fprintf(stderr,"\treferenced on line %d\n", p->lineno);
+ _p=p->next;
+ free(p);
+ }
+ undefs++;
+ }
+ _s=(*s)->next;
+ free(*s);
+ *s=_s;
+ }
+ else
+ {
+ s=&(*s)->next;
+ }
+ }
+ }
+
+ void destroy_locals(void)
+ {
+ Symbol **s=&symtab;
+ while (*s)
+ {
+ if (islocal((*s)->name))
+ {
+ Symbol *_s=*s;
+ if (!_s->defined && _s->patches)
+ {
+ Patch *p,*_p;
+ fprintf(stderr, "Undefined symbol `%s', first used on line %d\n", _s->name, _s->first_used);
+ for (p=_s->patches; p; p=_p) {
+ fprintf(stderr,"\treferenced on line %d\n", p->lineno);
+ _p=p->next;
+ free(p);
+ }
+ undefs++;
+ }
+ _s=(*s)->next;
+ free(*s);
+ *s=_s;
+ }
+ else
+ {
+ s=&(*s)->next;
+ }
+ }
+ }
+
void sortsyms(int (*sortf)(void const *,void const *))
{
int ns, i;
***************
*** 1452,1457 ****
--- 1801,1810 ----
v = s->value + offset;
emitw(v);
break;
+ case REL_abs8:
+ v = s->value + offset;
+ emitb(v);
+ break;
case REL_16:
v = s->value - pc - 2 + offset;
emitw(v);
***************
*** 1460,1466 ****
v = s->value - pc - 1 + offset;
if (v < -128 || v > 127)
{
! fprintf(stderr, "%s:%d: 8-bit relocation too big (%d); use long form", inname, lineno, v);
total_errors++;
}
emitb(v);
--- 1813,1819 ----
v = s->value - pc - 1 + offset;
if (v < -128 || v > 127)
{
! fprintf(stderr, "%s:%d: 8-bit relocation too big (%d); use long form\n", inname, lineno, v);
total_errors++;
}
emitb(v);
***************
*** 1486,1492 ****
case REL_8:
if (offset < -128 || offset > 127)
{
! fprintf(stderr, "%s:%d: 8-bit relocation offset too big (%d); use long form", inname, lineno, offset);
total_errors++;
}
emitb(offset);
--- 1839,1845 ----
case REL_8:
if (offset < -128 || offset > 127)
{
! fprintf(stderr, "%s:%d: 8-bit relocation offset too big (%d); use long form\n", inname, lineno, offset);
total_errors++;
}
emitb(offset);
***************
*** 1499,1504 ****
--- 1852,1887 ----
emitb((mod<<6) | (reg<<3) | rm);
}
+ int findreg(int regbits)
+ {
+ int i=0;
+ while (regbits) {
+ regbits>>=1;
+ i++;
+ }
+ return i?i-1:4;
+ }
+
+ int findscl(int sclbits)
+ {
+ static int bits[]={0,0,1,0,2,0,0,0,3};
+ return bits[sclbits];
+ }
+
+ int nooffset(int mbyte, int needsib)
+ {
+ if (_modrm.offset == 0 && _modrm.nsyms == 0) {
+ emitb(mbyte);
+ if (needsib)
+ emitb(mbyte>>8);
+ if (mbyte&0100)
+ emitb(0);
+ _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ return 1;
+ }
+ return 0;
+ }
+
int reg2mbyte[] = { 0x48, 0x88, 0x60, 0xa0, 0x40, 0x80, 0x20, 0x08 };
void reg(int which)
***************
*** 1506,1542 ****
int i;
int v;
int mbyte = which << 3;
! if (_modrm.regs == 0)
! {
! emitb(movacc ? movacc : mbyte + 6);
movacc=0;
! }
! else if (_modrm.regs == 0x20 && _modrm.offset == 0 && _modrm.nsyms == 0)
! {
! emitb(mbyte + 0x86);
! }
! else
! {
! for (i=0; i<8; i++)
! if (reg2mbyte[i] == _modrm.regs)
{
! mbyte |= i;
! break;
}
- if (i == 8)
- {
- printf("%s:%s: Invalid registers in R/M\n", inname, lineno);
- total_errors ++;
}
! if (_modrm.offset == 0 && _modrm.nsyms == 0)
! {
! emitb(mbyte);
! _modrm.nsyms = _modrm.regs = _modrm.offset = 0;
return;
! }
! emitb(mbyte + 0x80);
}
v = _modrm.offset;
for (i=0; i<_modrm.nsyms; i++)
{
--- 1889,1960 ----
int i;
int v;
int mbyte = which << 3;
+ int needsib = 0;
! if (_modrm.regs == 0) {
! /* This handles the case of displacement only addressing (no register
! * ofsets)
! */
! mbyte=movacc ? movacc : mbyte + (_modrm.addr32 ? 5 : 6);
movacc=0;
! } else if (_modrm.regs == 0x20 && _modrm.offset == 0 && _modrm.nsyms == 0) {
! /* [bp+0] */
! nooffset(mbyte|0106,0);
! return;
! } else {
! if (_modrm.addr32) {
! if (_modrm.addr32&0xff) {
! int sib= findreg( _modrm.addr32 &0xff) |
! (findreg((_modrm.addr32>>8 )&0xff)<<3)|
! (findscl((_modrm.addr32>>16)&0x0f)<<6);
! if (sib==045 && _modrm.offset == 0 && _modrm.nsyms == 0) {
! /* [ebp+0] */
! nooffset(mbyte|0104|(045<<8),1);
! return;
! } else if (sib==044) {
! /* [esp] */
! mbyte|=(sib<<8)|004;
! needsib=1;
! } else if ((sib&070)==0040) {
! /* no index */
! mbyte|=sib&007;
! } else if ((sib&007)==0005) {
! /* ebp is base */
! mbyte|=(sib<<8)|004;
! needsib=1;
! if (nooffset(mbyte|0100,1))
! return;
! } else {
! mbyte|=(sib<<8)|004;
! needsib=1;
! }
! } else {
! int sib=(005 )|
! (findreg((_modrm.addr32>>8 )&0xff)<<3)|
! (findscl((_modrm.addr32>>16)&0x0f)<<6);
! mbyte|=(sib<<8)|004;
! if (nooffset(mbyte|0200,1))
! return;
! }
! } else {
! /* 16 bit addressing */
! for (i=0; i<8; i++)
! if (reg2mbyte[i] == _modrm.regs)
! {
! mbyte |= i;
! break;
! }
! if (i == 8)
{
! fprintf(stderr,"%s:%d: Invalid registers in R/M\n", inname, lineno);
! total_errors ++;
}
}
! if (nooffset(mbyte,needsib))
return;
! mbyte|=0200;
}
+
v = _modrm.offset;
for (i=0; i<_modrm.nsyms; i++)
{
***************
*** 1549,1564 ****
p = (Patch *)malloc(sizeof(Patch));
p->next = s->patches;
s->patches = p;
! p->location = pc;
p->lineno = lineno;
! p->rel = REL_abs;
}
! }
! emitw(v);
! _modrm.nsyms = _modrm.regs = _modrm.offset = 0;
}
! int yylex()
{
last_tret = yylex1();
return last_tret;
--- 1967,2041 ----
p = (Patch *)malloc(sizeof(Patch));
p->next = s->patches;
s->patches = p;
! p->location = pc+1; /* ALL bytes emitted below, accounts for yet to be emitted mbyte */
p->lineno = lineno;
! p->rel = _modrm.addr32 ? REL_abs32 : REL_abs;
! _modrm.regs=0; /* force offset field to be full size (2/4 bytes rather than 1) */
}
! }
! if (_modrm.regs && v>=-128 && v<=127) {
! emitb(mbyte^0300); /* change mod from 2/4 ((d)word offset) to 1 (byte offset) */
! if (needsib)
! emitb(mbyte>>8);
! emitb(v);
! } else {
! emitb(mbyte);
! if (needsib)
! emitb(mbyte>>8);
! if (_modrm.addr32)
! emitd(v);
! else
! emitw(v);
! }
!
! _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
}
! void addr32(int sib)
! {
! char *err=0;
!
! if (_modrm.addr16) {
! err="Cannot mix 16 and 32 bit addressing";
! } else {
! if (!_modrm.addr32) emitb(0x67);
! _modrm.addr32|=0x1000000;
! if ((sib&0xf00)>0x100) {
! if ((sib&0xff)==0x10) {
! err="esp cannot be scaled";
! } else if (_modrm.addr32&0xff00) {
! err="scaled index already used";
! } else {
! _modrm.addr32|=sib<<8;
! }
! } else {
! if (!(_modrm.addr32&0xff)) {
! _modrm.addr32|=(sib&0xff)|0x1000000;
! } else if (!(_modrm.addr32&0xff00)) {
! if ((sib&0xff)==0x10) {
! if ((_modrm.addr32&0xff)==0x10) {
! err="esp cannot be the index";
! } else {
! _modrm.addr32=(_modrm.addr32&0xff)<<8;
! _modrm.addr32|=(sib&0xff)|0x1010000;
! }
! } else {
! _modrm.addr32|=sib<<8;
! }
! } else {
! err="scaled index already used";
! }
! }
! }
! if (err) {
! yyerror(err);
! _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
! } else {
! _modrm.regs=-1;
! }
! }
!
! int yylex(void)
{
last_tret = yylex1();
return last_tret;
***************
*** 1568,1584 ****
char c1, c2;
int token;
} twochars[] = {
! '=', '=', '=',
! '>', '=', OP_GE,
! '<', '=', OP_LE,
! '<', '>', OP_NE,
! '!', '=', OP_NE,
! '&', '&', OP_AND,
! '|', '|', OP_OR,
! '<', '<', OP_SHL,
! '>', '>', OP_SHR};
! int yylex1()
{
int c, c2, i, oldc;
struct opcode *opp, op;
--- 2045,2062 ----
char c1, c2;
int token;
} twochars[] = {
! {'=', '=', '='},
! {'>', '=', OP_GE},
! {'<', '=', OP_LE},
! {'<', '>', OP_NE},
! {'!', '=', OP_NE},
! {'&', '&', OP_AND},
! {'|', '|', OP_OR},
! {'<', '<', OP_SHL},
! {'>', '>', OP_SHR}
! };
! int yylex1(void)
{
int c, c2, i, oldc;
struct opcode *opp, op;
***************
*** 1610,1617 ****
case '$':
case '.':
case '@':
! ungetc(c, infile);
! fscanf(infile, "%[a-zA-Z0-9_$.@]", strbuf);
strcpy(last_token, strbuf);
if (strcmp(strbuf, ".") == 0)
return PC;
--- 2088,2104 ----
case '$':
case '.':
case '@':
! case '?':
! if (c=='?')
! {
! strbuf[0]=c;
! fscanf(infile, "%[a-zA-Z0-9_$.@]", strbuf+1);
! }
! else
! {
! ungetc(c, infile);
! fscanf(infile, "%[a-zA-Z0-9_$.@]", strbuf);
! }
strcpy(last_token, strbuf);
if (strcmp(strbuf, ".") == 0)
return PC;
***************
*** 1723,1728 ****
--- 2210,2221 ----
return 1;
}
+ int islocal(char *symname)
+ {
+ if (symname[0]!='?') return 0;
+ return 1;
+ }
+
void do_sreg_pop(int sreg)
{
switch (sreg)
***************
*** 1859,1865 ****
return;
}
}
! printf("Unknown output type: `%s'\n", t);
}
void set_image_type(char *t)
--- 2352,2358 ----
return;
}
}
! fprintf(stderr,"Unknown output type: `%s'\n", t);
}
void set_image_type(char *t)
***************
*** 1883,1889 ****
return;
}
}
! printf("Unknown output type: `%s'\n", t);
}
void do_include(char *fname)
--- 2376,2382 ----
return;
}
}
! fprintf(stderr,"Unknown output type: `%s'\n", t);
}
void do_include(char *fname)
***************
*** 1922,1933 ****
SCNHDR *f_thdr; /* Text section header */
SCNHDR *f_dhdr; /* Data section header */
SCNHDR *f_bhdr; /* Bss section header */
! AOUTHDR f_ohdr; /* Optional file header (a.out) */
SYMENT *symbol;
RELOC *rp;
int cnt, i;
void *base;
! int textbase, database, bssbase, delta;
char smallname[9];
f = open (filename, O_RDONLY | O_BINARY);
--- 2415,2426 ----
SCNHDR *f_thdr; /* Text section header */
SCNHDR *f_dhdr; /* Data section header */
SCNHDR *f_bhdr; /* Bss section header */
! /* AOUTHDR f_ohdr;*/ /* Optional file header (a.out) */
SYMENT *symbol;
RELOC *rp;
int cnt, i;
void *base;
! int textbase, database, bssbase/*, delta*/;
char smallname[9];
f = open (filename, O_RDONLY | O_BINARY);
***************
*** 1966,1974 ****
emitb (0);
#ifdef DEBUG_RELOC
! printf ("textbase is at %04x\n", textbase);
! printf ("database is at %04x\n", database);
! printf ("bssbase is at %04x\n", bssbase);
#endif
symbol = (void *) data + header->f_symptr;
--- 2459,2467 ----
emitb (0);
#ifdef DEBUG_RELOC
! printf (stderr,"textbase is at %04x\n", textbase);
! printf (stderr,"database is at %04x\n", database);
! printf (stderr,"bssbase is at %04x\n", bssbase);
#endif
symbol = (void *) data + header->f_symptr;
***************
*** 2000,2006 ****
break;
case N_UNDEF:
if (symbol->e_value == 0)
! 0; /* Nothing -- external reference. */
else if (!get_symbol (p, 0))
{
/* New common variable. */
--- 2493,2499 ----
break;
case N_UNDEF:
if (symbol->e_value == 0)
! /*0*/; /* Nothing -- external reference. */
else if (!get_symbol (p, 0))
{
/* New common variable. */
***************
*** 2028,2034 ****
for (; cnt > 0; cnt--, rp++)
{
! Symbol *s;
int delta;
if (symbol[rp->r_symndx].e.e.e_zeroes == 0)
--- 2521,2527 ----
for (; cnt > 0; cnt--, rp++)
{
! Symbol *s=0;
int delta;
if (symbol[rp->r_symndx].e.e.e_zeroes == 0)
--Message-Boundary-28453--
- Raw text -