Como acessar C struct / variáveis do inline asm?

Considere o seguinte código:

    int bn_div(bn_t *bn1, bn_t *bn2, bn_t *bnr)
  {
    uint32 q, m;        /* Division Result */
    uint32 i;           /* Loop Counter */
    uint32 j;           /* Loop Counter */

    /* Check Input */
    if (bn1 == NULL) return(EFAULT);
    if (bn1->dat == NULL) return(EFAULT);
    if (bn2 == NULL) return(EFAULT);
    if (bn2->dat == NULL) return(EFAULT);
    if (bnr == NULL) return(EFAULT);
    if (bnr->dat == NULL) return(EFAULT);


    #if defined(__i386__) || defined(__amd64__)
    __asm__ (".intel_syntax noprefix");
    __asm__ ("pushl %eax");
    __asm__ ("pushl %edx");
    __asm__ ("pushf");
    __asm__ ("movl %eax, (bn1->dat[i])");
    __asm__ ("xorl %edx, %edx");
    __asm__ ("divl (bn2->dat[j])");
    __asm__ ("movl (q), %eax");
    __asm__ ("movl (m), %edx");
    __asm__ ("popf");
    __asm__ ("popl %edx");
    __asm__ ("popl %eax");
    #else
    q = bn->dat[i] / bn->dat[j];
    m = bn->dat[i] % bn->dat[j];
    #endif
    /* Return */
    return(0);
  }

Os tipos de dados uint32 são basicamente um int longo não assinado ou um inteiro de 32 bits não assinado uint32_t. O tipo bnint é um int curto não assinado (uint16_t) ou uint32_t, dependendo se os tipos de dados de 64 bits estão disponíveis ou não. Se 64 bits estiver disponível, bnint é um uint32, caso contrário, é um uint16. Isso foi feito para capturar carry / overflow em outras partes do código. A estrutura bn_t é definida da seguinte forma:

typedef struct bn_data_t bn_t;
struct bn_data_t
  {
    uint32 sz1;         /* Bit Size */
    uint32 sz8;         /* Byte Size */
    uint32 szw;         /* Word Count */
    bnint *dat;         /* Data Array */
    uint32 flags;       /* Operational Flags */
  };

A função começa na linha 300 no meu código-fonte. Portanto, quando tento compilar / executar, recebo os seguintes erros:

system:/home/user/c/m3/bn 1036 $$ ->make
clang -I. -I/home/user/c/m3/bn/.. -I/home/user/c/m3/bn/../include  -std=c99 -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes  -Wmissing-prototypes -Wnested-externs -Wwrite-strings -Wfloat-equal  -Winline -Wunknown-pragmas -Wundef -Wendif-labels  -c /home/user/c/m3/bn/bn.c
/home/user/c/m3/bn/bn.c:302:12: warning: unused variable 'q' [-Wunused-variable]
    uint32 q, m;        /* Division Result */
           ^
/home/user/c/m3/bn/bn.c:302:15: warning: unused variable 'm' [-Wunused-variable]
    uint32 q, m;        /* Division Result */
              ^
/home/user/c/m3/bn/bn.c:303:12: warning: unused variable 'i' [-Wunused-variable]
    uint32 i;           /* Loop Counter */
           ^
/home/user/c/m3/bn/bn.c:304:12: warning: unused variable 'j' [-Wunused-variable]
    uint32 j;           /* Loop Counter */
           ^
/home/user/c/m3/bn/bn.c:320:14: error: unknown token in expression
    __asm__ ("movl %eax, (bn1->dat[i])");
             ^
<inline asm>:1:18: note: instantiated into assembly here
        movl %eax, (bn1->dat[i])
                        ^
/home/user/c/m3/bn/bn.c:322:14: error: unknown token in expression
    __asm__ ("divl (bn2->dat[j])");
             ^
<inline asm>:1:12: note: instantiated into assembly here
        divl (bn2->dat[j])
                  ^
4 warnings and 2 errors generated.
*** [bn.o] Error code 1

Stop in /home/user/c/m3/bn.
system:/home/user/c/m3/bn 1037 $$ ->

O que eu sei

Considero-me bastante versado no assembler x86 (como evidenciado no código que escrevi acima). No entanto, a última vez que misturei uma linguagem de alto nível e o assembler estava usando o Borland Pascal cerca de 15 a 20 anos atrás, ao escrever drivers gráficos para jogos (era anterior ao Windows 95). Minha familiaridade é com a sintaxe da Intel.

O que eu não sei:

Como acesso membros de bn_t (especialmente * dat) do asm? Como * dat é um ponteiro para uint32, estou acessando os elementos como uma matriz (por exemplo: bn1-> dat [i]).

Como acesso variáveis locais declaradas na pilh

Estou usando push / pop para restaurar os registros acumulados para seus valores anteriores, de modo a não perturbar o compilador. No entanto, também preciso incluir a palavra-chave volátil nas variáveis locais?

Or, existe uma maneira melhor de que eu não saiba? Não quero colocar isso em uma chamada de função separada por causa da sobrecarga de chamada, pois essa função é essencial para o desempenh

Adicional

Agora, estou apenas começando a escrever esta função, então não é onde está completa. Faltam loops e outros códigos de suporte / cola. Mas, a essência principal é acessar variáveis locais / elementos de estrutur

EDIT 1:

A sintaxe que estou usando parece ser a única suportada pelo clang. Eu tentei o seguinte código e clang me deu todos os tipos de erros:

__asm__ ("pushl %%eax",
    "pushl %%edx",
    "pushf",
    "movl (bn1->dat[i]), %%eax",
    "xorl %%edx, %%edx",
    "divl ($0x0c + bn2 + j)",
    "movl %%eax, (q)",
    "movl %%edx, (m)",
    "popf",
    "popl %%edx",
    "popl %%eax"
    );

Deseja que eu coloque um parêntese de fechamento na primeira linha, substituindo a vírgula. Eu mudei para usar %% em vez de% porque li em algum lugar que o assembly embutido requer que %% denote registros da CPU, e clang estava me dizendo que eu estava usando uma sequência de escape inválida.

questionAnswers(1)

yourAnswerToTheQuestion