mardi 15 avril 2014

simulateur - C: Comment puis-je simuler 8086 registres ? -Débordement de pile


Ohai, I'm currently trying to implement an 8086 ASM debugger for learning purposes. Until now, I tried to simulate the 8 and 16 bit registers with char arrays but this approach is driving me nuts, when working with AX, AL and AH.


#define setAL() { int i; for (i = 0; i < 8; i++) AL[i] = AX[i]; }
char AX[16] = {0, 1, 1, 1, 1 ,1 ,1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char AL[8] = {0, 0, 0, 0, 0, 0, 0, 0};

Does anyone has any good idea (or something like 'best practice') how to simulate those registers?




I don't think there's a 'best practice' way of doing this, but one approach you could take that may drive you nuts less is to use a union to overlay the 8 and 16 bit portions:


struct RegByte { 
unsigned char low;
unsigned char high;
};

struct RegWord {
unsigned short value;
};

union Reg {
struct RegWord word;
struct RegByte bytes;
};

Alternatively given you're explicitly targeting just 8086 you could have one structure containing all the 16 bit registers and one containing all of the byte portions. e.g.


struct RegByte {
unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};

struct RegWord {
unsigned short ax, bx, cx, dx;
/* nothing stopping you from continuing with si, di, etc even though
* they don't have addressable high and low bytes */
};

union Reg {
struct RegWord word;
struct RegByte byte;
};



I'd abstract the structure away and use accessor functions.


struct registry_file_t;
uint16_t get_al(registry_file_t * r);
void set_al(registry_file_t * r, uint16_t value);

With inlining enabled, this approach will be no less performant than using a union.




Why not use structure and union like this:


union AX_R {
AX_R() {
AX = 0;
}
unsigned __int16 AX;
struct {
unsigned __int8 AL;
unsigned __int8 AH;
} _AX_R;
};


Ohai, I'm currently trying to implement an 8086 ASM debugger for learning purposes. Until now, I tried to simulate the 8 and 16 bit registers with char arrays but this approach is driving me nuts, when working with AX, AL and AH.


#define setAL() { int i; for (i = 0; i < 8; i++) AL[i] = AX[i]; }
char AX[16] = {0, 1, 1, 1, 1 ,1 ,1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char AL[8] = {0, 0, 0, 0, 0, 0, 0, 0};

Does anyone has any good idea (or something like 'best practice') how to simulate those registers?



I don't think there's a 'best practice' way of doing this, but one approach you could take that may drive you nuts less is to use a union to overlay the 8 and 16 bit portions:


struct RegByte { 
unsigned char low;
unsigned char high;
};

struct RegWord {
unsigned short value;
};

union Reg {
struct RegWord word;
struct RegByte bytes;
};

Alternatively given you're explicitly targeting just 8086 you could have one structure containing all the 16 bit registers and one containing all of the byte portions. e.g.


struct RegByte {
unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};

struct RegWord {
unsigned short ax, bx, cx, dx;
/* nothing stopping you from continuing with si, di, etc even though
* they don't have addressable high and low bytes */
};

union Reg {
struct RegWord word;
struct RegByte byte;
};


I'd abstract the structure away and use accessor functions.


struct registry_file_t;
uint16_t get_al(registry_file_t * r);
void set_al(registry_file_t * r, uint16_t value);

With inlining enabled, this approach will be no less performant than using a union.



Why not use structure and union like this:


union AX_R {
AX_R() {
AX = 0;
}
unsigned __int16 AX;
struct {
unsigned __int8 AL;
unsigned __int8 AH;
} _AX_R;
};

Related Posts:

0 commentaires:

Enregistrer un commentaire