Skip to main content
GameDev.net gamedev.net
🔒 Locked

Inline asm and C structures

Started by juturnas Feb 20, 2009 at 7:37 PM 1 replies 900+ views
Original Post
juturnas
juturnas
I've just started working with inline assembly in VC++ express edition (just for fun). I've run into a problem when working with pointers & structures.


typedef struct {
    int a;
} class1;

typedef struct {
    int a;
} class2;

void do_something() {

 	class1 x;
	class2 y;

	class1 *i = &x
	class2 *j = &y

	int foo;

	__asm {
		/* Add x.a and y.a directly, works fine */
		mov eax, x.a
		add eax, y.a
		

		/* Add x.a and y.a through pointers, doesn't work */
		mov eax, i
		mov eax, [eax].a

		mov ebx, j
		mov ebx, [ebx].a

		add eax, ebx
    }
}


Adding x.a and y.a through pointers doesn't work, because a is a field of both class1 and class2. I thought I had read you could access it like this:

add eax, [ebx].class1.a

But that doesn't seem to work either. I suppose when only given [ebx].a, the compiler can't infer what type it would be. So I'm not sure if I'm making a syntactic error, or if I should be doing this in an entirely different fashion. Anyway, any help would be appreciated. Thanks for reading, Juturnas
Drew_Benton
Drew_Benton
Quote:
Original post by juturnas
So I'm not sure if I'm making a syntactic error, or if I should be doing this in an entirely different fashion.


That is a syntactic error because of how [] are used in assembly. You cannot use a pointer to an object and access it's fields by name in assembly as far as I know.

If you wanted to go that route, you'd have to specify the memory offsets to the fields yourself. Luckily, you can use a little macro provided in stddef to know that. Here is a quick little example to give you an idea.

#include <stdio.h>#include <stddef.h>typedef struct {	int a;	int b;	int c;} class1;typedef struct {	int a;	char q;	int b;	int c;} class2;int main(int argc, char** argv){	int foo = 0;	printf("Foo: %i\n", foo);	class1 x;	x.a = 1;	x.b = 2;	x.c = 3;	class2 y;	y.a = 4;	y.b = 5;	y.c = 6;	y.q = 8;	class1 *i = &x	class2 *j = &y	printf("%i\t%i\t%i\n", offsetof(class1, a), offsetof(class1, b), offsetof(class1, c));	printf("%i\t%i\t%i\t%i\n", offsetof(class2, a), offsetof(class2, q), offsetof(class2, b), offsetof(class2, c));	int offsetOf_class1_a = offsetof(class1, a);	int offsetOf_class2_b = offsetof(class2, b);	__asm 	{		mov eax, i		add eax, offsetOf_class1_a		mov eax, [eax]		mov ecx, j		add ecx, offsetOf_class2_b		mov ecx, [ecx]		add eax, ecx		mov foo, eax	}	printf("Foo: %i\n", foo);	return 0;}


That is the way to go if you wish to use pointers and access fields by name, you would just be using your own name offset rather than the structure's own. Hope that helps!
juturnas
juturnas
Thanks! I was beginning to think it just wasn't the right way to do it, but I didn't see any alternatives. I was getting bored trying to figure it out on my own :) I appreciate the response!

Juturnas

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.