123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- #include "arg_type.h"
- #include "as.h"
- #define last( s) ( s + strlen( s) - 1)
- #define LEFT '('
- #define RIGHT ')'
- #define DOLLAR '$'
- block_assemble( instr, nr, first, Last)
- char **instr;
- int nr, first, Last;
- {
- int i;
- /*
- if ( first) {
- if( strncmp( instr[0], "pop", 3) == 0) {
- *instr[0] = 'P';
- *( instr[0]+1) = 'O';
- *( instr[0]+2) = 'P';
- }
- else
- @clean_push_buf();
- }
- if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
- *instr[nr-1] = 'P';
- *( instr[nr-1]+1) = 'U';
- *( instr[nr-1]+2) = 'S';
- *( instr[nr-1]+3) = 'H';
- }
- */
- for( i=0; i<nr; i++)
- assemble( instr[i]);
- }
- process_label( l)
- char *l;
- {
- }
- process_mnemonic( m)
- char *m;
- {
- }
- process_operand( str, op)
- char *str;
- struct t_operand *op;
- /* expr -> IS_DATA en IS_LABEL
- * reg -> IS_REG en IS_ACCU
- * (expr) -> IS_ADDR
- * expr(reg) -> IS_MEM
- */
- {
- char *ptr, *strchr();
- op->type = UNKNOWN;
- if ( *last( str) == RIGHT) {
- ptr = strchr( str, LEFT);
- *last( str) = '\0';
- *ptr = '\0';
- if ( is_reg( ptr+1, op)) {
- op->type = IS_MEM;
- op->expr = ( *str == '\0' ? "0" : str);
- }
- else {
- set_label( ptr+1, op);
- op->type = IS_ADDR;
- }
- }
- else
- if ( is_reg( str, op))
- op->type = IS_REG;
- else {
- if ( contains_label( str))
- set_label( str, op);
- else {
- op->type = IS_DATA;
- op->expr = str;
- }
- }
- }
- static struct regnam {
- char *regstr;
- int regval;
- } regnam[] = {
- { "eax", 0 },
- { "ebx", 3 },
- { "ecx", 1 },
- { "edx", 2 },
- { "esp", 4 },
- { "ebp", 5 },
- { "esi", 6 },
- { "edi", 7 },
- { "al", 0 },
- { "bl", 3 },
- { "cl", 1 },
- { "dl", 2 },
- { "ah", 4 },
- { "bh", 7 },
- { "ch", 5 },
- { "dh", 6 },
- { 0, 0}
- }
- ;
- int is_reg( str, op)
- char *str;
- struct t_operand *op;
- {
- register struct regnam *p = regnam;
- while (p->regstr) {
- if (! strcmp(p->regstr, str)) {
- op->reg = p->regval;
- return TRUE;
- }
- p++;
- }
- return FALSE;
- }
- #include <ctype.h>
- #define isletter( c) ( isalpha( c) || c == '_')
- int contains_label( str)
- char *str;
- {
- while( !isletter( *str) && *str != '\0')
- if ( *str == '$')
- if ( arg_type( str) == STRING)
- return( TRUE);
- else
- str += 2;
- else
- str++;
- return( isletter( *str));
- }
- set_label( str, op)
- char *str;
- struct t_operand *op;
- {
- char *ptr, *strchr(), *sprint();
- static char buf[256];
- ptr = strchr( str, '+');
- if ( ptr == 0)
- op->off = "0";
- else {
- *ptr = '\0';
- op->off = ptr + 1;
- }
- if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
- *(str+2) == '\0') {
- *(str+1) = '\0'; /* remove b or f! */
- op->lab = str;
- op->type = IS_ILB;
- }
- else {
- op->type = IS_LABEL;
- if ( strchr( str, DOLLAR) != 0)
- op->lab = str;
- else
- op->lab = sprint( buf, "\"%s\"", str);
- }
- }
- /******************************************************************************/
- mod_RM( reg, op)
- int reg;
- struct t_operand *op;
- {
- if ( REG( op))
- R233( 0x3, reg, op->reg);
- else if ( ADDR( op)) {
- R233( 0x0, reg, 0x5);
- @reloc4( %$(op->lab), %$(op->off), ABSOLUTE);
- }
- else if ( strcmp( op->expr, "0") == 0)
- switch( op->reg) {
- case AX:
- case BX:
- case CX:
- case DX:
- case DI:
- case SI: R233( 0x0, reg, op->reg);
- break;
- case BP : R233( 0x1, reg, 0x6); /* Exception! */
- @text1( 0);
- break;
- default : fprint( STDERR, "Wrong index register %d\n",
- op->reg);
- }
- else {
- if (isdigit(op->expr[0])) {
- long l, atol();
- l = atol(op->expr);
- if ( l <= 127 && l >= -128) {
- switch( op->reg) {
- case AX:
- case BX:
- case CX:
- case DX:
- case DI:
- case BP:
- case SI : R233( 0x1, reg, op->reg);
- break;
-
- default : fprint( STDERR, "Wrong index register %d\n",
- op->reg);
- }
- @text1( %$(op->expr));
- } else {
- switch( op->reg) {
- case AX:
- case BX:
- case CX:
- case DX:
- case DI:
- case BP:
- case SI : R233( 0x2, reg, op->reg);
- break;
-
- default : fprint( STDERR, "Wrong index register %d\n",
- op->reg);
- }
- @text4( %$(op->expr));
- }
- } else {
- @if ( fit_byte( %$(op->expr)))
- switch( op->reg) {
- case AX:
- case BX:
- case CX:
- case DX:
- case DI:
- case BP:
- case SI : R233( 0x1, reg, op->reg);
- break;
-
- default : fprint( STDERR, "Wrong index register %d\n",
- op->reg);
- }
- @text1( %$(op->expr));
- @else
- switch( op->reg) {
- case AX:
- case BX:
- case CX:
- case DX:
- case DI:
- case BP:
- case SI : R233( 0x2, reg, op->reg);
- break;
-
- default : fprint( STDERR, "Wrong index register %d\n",
- op->reg);
- }
- @text4( %$(op->expr));
- @fi
- }
- }
- }
- mv_RG_EADDR( dst, src)
- struct t_operand *dst, *src;
- {
- if ( REG(src) && dst->reg == src->reg)
- ; /* Nothing!! result of push/pop optimization */
- else {
- @text1( 0x8b);
- mod_RM( dst->reg, src);
- }
- }
- R233( a, b, c)
- int a,b,c;
- {
- @text1( %d( (a << 6) | ( b << 3) | c));
- }
- R53( a, b)
- int a,b;
- {
- @text1( %d( (a << 3) | b));
- }
- small_const(opc, src)
- struct t_operand *src;
- {
- if (isdigit(src->expr[0])) {
- long l, atol();
- l = atol(src->expr);
- if (l >= -128 && l <= 127) {
- @text1(%d(opc|02));
- @text1(%$(src->expr));
- }
- else {
- @text1(%d(opc));
- @text4(%$(src->expr));
- }
- }
- else {
- @if (fit_byte(%$(src->expr)))
- @text1(%d(opc|02));
- @text1(%$(src->expr));
- @else
- @text1(%d(opc));
- @text4(%$(src->expr));
- @fi
- }
- }
- small_RMconst(opc, reg, dst, src)
- struct t_operand *dst, *src;
- {
- if (isdigit(src->expr[0])) {
- long l, atol();
- l = atol(src->expr);
- if (l >= -128 && l <= 127) {
- @text1(%d(opc|02));
- mod_RM(reg, dst);
- @text1(%$(src->expr));
- }
- else {
- @text1(%d(opc));
- mod_RM(reg, dst);
- @text4(%$(src->expr));
- }
- }
- else {
- @if (fit_byte(%$(src->expr)))
- @text1(%d(opc|02));
- mod_RM(reg, dst);
- @text1(%$(src->expr));
- @else
- @text1(%d(opc));
- mod_RM(reg, dst);
- @text4(%$(src->expr));
- @fi
- }
- }
|