Page 1 of 1

Problem with C

Posted: Sun Jul 28, 2013 5:43 am
by computertrick
Hi i am quite new to C and I have an issue with it.

I am developing a x86 emulator here is some test code that's trying to point to an index in an array.

Code: Select all

unsigned int *reg_16[16];
	unsigned char *reg_8[8];
	reg_16[0] = &reg_8[4];
	reg_16[1] = &reg_8[0];
	
	reg_8[4] = 6;
	reg_8[0] = 4;
	printf("0x%x", *reg_16[0]);
The reason for this is so if you change an 8 bit register or a 16 bit register they will both update. The problem is I get warnings
cpu.c: In function ‘cpu_exec’:
cpu.c:18: warning: assignment from incompatible pointer type
cpu.c:19: warning: assignment from incompatible pointer type
cpu.c:21: warning: assignment makes pointer from integer without a cast
cpu.c:22: warning: assignment makes pointer from integer without a cast
x86Emu compiled!
Also my code is slightly wrong how can I change the 16 bit integer by char without changing its datatype

Re: Problem with C

Posted: Sun Jul 28, 2013 5:55 am
by HugeCode
& operator doesn't return int *, so you need to cast it to char *. But why are you trying to conver one char pointer on index 4 to int pointer and then you skip continuing 3 pointers?

Code: Select all

reg_8[4] = 6;
reg_8[0] = 4;
You can't do this since 6 and 4 aren't char pointers.
I think you want to do something like this:

Code: Select all

#define REGISTER_COUNT 8 /* omitting segment registers */
/*note that MODR/M byte has different order for registers */
#define AL 0
#define AH 1
#define BL 2
#define BH 3
....
#define AX 0
#define BX 1
....

char reg_content[REGISTER_COUNT*WORD_SIZE_BYTES];
char * reg_8[REGISTER_COUNT];
short * reg_16[REGISTER_COUNT];
....

void setup_registers() {
    for(int reg_i = 0;reg_i < REGISTER_COUNT;reg_i++) {
        reg_8[reg_i] = &reg_content + reg_i;
    }
    
    for(int reg_i = 0;reg_i < REGISTER_COUNT;reg_i++) {
        reg_16[reg_i] = (short*)(&reg_content + reg_i*WORD_SIZE_BYTES);
    }
}
...

/* somewhere in code */
*(reg_8[AL]) = 4;
*(reg_16[AX]) = 4;
*(reg_16[SP]) = 0x3FF;

/* you will manipulate with registers very often, so these definitions would be better */
#define reg8(n) *(reg_8[n])
#define reg16(n) *(reg_16[n])

#define AL reg8(0)
#define AH  reg8(1)
#define AX reg16(0)
....

/* somewhere in code */
if(insnSize==8) {
    reg8((modrm>>3)&7) += reg8(modrm&7);
}

/* or when modrm isn't specified (movsb)*/
mem(segoff(DS, DI)) = mem(segoff(DS, SI));

Re: Problem with C

Posted: Sun Jul 28, 2013 6:29 am
by bluemoon
computertrick wrote:Hi i am quite new to C and I have an issue with it.
I am developing a x86 emulator here (snipped)
For learning purpose, I truly suggest you do a calculator instead. As a side note, you will get more help with general programming issue on forum like stackoverflow.
computertrick wrote:The reason for this is so if you change an 8 bit register or a 16 bit register they will both update.
Learn union.

Re: Problem with C

Posted: Sun Sep 29, 2013 9:14 pm
by kiara
:shock:

Re: Problem with C

Posted: Tue Oct 01, 2013 3:59 pm
by qw
Pointers keep confusing people.

reg_8[x] isn't pointing anywhere.
&reg_8[x] returns the address of a pointer to unsigned char (unsigned char **) which is assigned to reg_16[x] which is a pointer to unsigned int.

Why use pointers in the first place?

Re: Problem with C

Posted: Tue Oct 08, 2013 9:52 pm
by Jvac
see here C Programming/Pointers and arrays

and if that does not work try the cboard Forums

Enjoy!