Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Open Watcom] Accessing a struct member through in-line assembly

229 views
Skip to first unread message

Mateusz Viste

unread,
Feb 15, 2017, 12:42:20 PM2/15/17
to
Hello programmers,

I am using some in-line assembly in Open Watcom, and I'm quite pleased at
how it works. However, there is one detail that I cannot grasp: how is
one supposed to use members of C structures from within in-line assembly?

Accessing a "normal" variable is easy, and works amazingly well:

unsigned short myax = 1;
_asm {
mov ax, myax
int 21h
}

...but how could I access a member of a C struct?

struct s {
unsigned short x;
unsigned short y;
} mystruct;

_asm {
mov ax, mystruct.x
}

The above example doesn't work of course. The assembler doesn't
understand what "mystruct.x" is about. I tried different desperate
things, like [mystruct.x], (mystruct.x), %mystruct.x or even $mystruct.x,
but the assembler isn't recognizing any. The only combination that did
"something" is using this:
mov ax, *mystruct.x

But the result is definitely not what I wanted, so I don't know what the
* operator is supposed to mean in such context.

While I am aware that there is no such thing as a "structure" in asm, I'd
expect Watcom to be smart enough to substitute struct members by their
offset relative to the struct's base. Is that possible at all with wasm,
or am I too wishful? Also, any idea on what the "*" operator used in the
above example might possibly mean? Unfortunately, the in-line Watcom
assembly is sparsely document.

Mateusz

Trifle Menot

unread,
Feb 15, 2017, 3:48:16 PM2/15/17
to
On 15 Feb 2017 17:42:19 GMT, Mateusz Viste
<mateus...@localhost.localhost> wrote:

>While I am aware that there is no such thing as a "structure" in asm, I'd
>expect Watcom to be smart enough to substitute struct members by their
>offset relative to the struct's base

With Borland C++ you can print out the assembly, and code the offset
yourself, via more asm statements. But then you must manually maintain
the asm code to match any change to the structure.


>or am I too wishful?

Maybe.



Johann Klammer

unread,
Feb 15, 2017, 6:15:36 PM2/15/17
to
On 02/15/2017 06:42 PM, Mateusz Viste wrote:
> While I am aware that there is no such thing as a "structure" in asm, I'd
> expect Watcom to be smart enough to substitute struct members by their
> offset relative to the struct's base. Is that possible at all with wasm,
> or am I too wishful? Also, any idea on what the "*" operator used in the
> above example might possibly mean? Unfortunately, the in-line Watcom
> assembly is sparsely document.
>
> Mateusz
>

I think that one was always broken....
maybe open an issue on github.

Mateusz Viste

unread,
Feb 16, 2017, 3:19:43 AM2/16/17
to
On Wed, 15 Feb 2017 20:48:16 +0000, Trifle Menot wrote:
> With Borland C++ you can print out the assembly, and code the offset
> yourself, via more asm statements. But then you must manually maintain
> the asm code to match any change to the structure.

With OpenWatcom it's even easier than that (but still cumbersome):

#define MYSTRUCT_OFF_X 0
#define MYSTRUCT_OFF_Y 2
struct s {
unsigned short x;
unsigned short y;
} mystruct;

_asm {
mov word ptr [mystruct] + MYSTRUCT_OFF_X, ax
}

I have been using the above since some time now... and it works fine, the
preprocessor takes care of resolving #defines also within in-line
assembly blocks. It does require of course to adjust the defines each
time that the structure evolves. I am only wondering whether OpenWatcom
perhaps provides some more elegant trick for handling that in an
automated way - it does seem trivial after all (at least compared to the
other magic that OW is capable of). That is, some asm-aware equivalent of
the C offsetof() macro...

Mateusz

Alexei A. Frounze

unread,
Feb 16, 2017, 5:46:05 AM2/16/17
to
I didn't find a way to pass a compile-time rather than
preprocess-time constants to assembly code, but you can still
enforce correctness of your macro values:

#include <stddef.h>
#include <stdio.h>

#define STATIC_ASSERT(EXPR) extern char StAtIc_AsSeRt[(EXPR) ? 1 : -1];

struct s
{
unsigned short x;
unsigned short y;
} mystruct = { 111, 222 };

#define MYSTRUCT_OFF_X 0
#define MYSTRUCT_OFF_Y 2

STATIC_ASSERT(MYSTRUCT_OFF_X == offsetof(struct s, x));
STATIC_ASSERT(MYSTRUCT_OFF_Y == offsetof(struct s, y));

int get_mx(void)
{
_asm movzx eax, word ptr [mystruct + MYSTRUCT_OFF_X]
}

int get_my(void)
{
_asm movzx eax, word ptr [mystruct + MYSTRUCT_OFF_Y]
}

int main(void)
{
printf("%d\n", get_mx());
printf("%d\n", get_my());
return 0;
}

Alex
0 new messages