gnu 内联汇编错误

Posted

技术标签:

【中文标题】gnu 内联汇编错误【英文标题】:gnu inline assembly error 【发布时间】:2012-12-02 03:23:08 【问题描述】:

我正在尝试在 C 文件中编写内联汇编,但出现 2 个错误:

open.c:10: Error: junkptr nombre' 在表达式后`

open.c:10: Error: suffix or operands invalid forles'`

这是我的文件:

int open(char * nombre, unsigned char modo)

  int retval;
  int nrllamada = 6;
  asm("mov $8,%%ah \n\t"
      "les %%bx, dword ptr nombre \n\t"
      "int $0x22 \n\t"
      "mov %%eax,%0 \n\t"
      : "=r"(retval)
      : "a"(modo)
  );
  return retval;

【问题讨论】:

【参考方案1】:
"les %%bx, dword ptr nombre \n\t"

你的字符串中有 ptr 名词。那可能是不正确的。您确定要在函数的参数中引用 char* 名词吗?

【讨论】:

【参考方案2】:

在寄存器 ES 和 BX 中写入名为 nombre 的 32 位指针的正确方法是将 C 变量 nombre 连接到寄存器 ECX,将 ECX 的低 16 位移动到寄存器 BX,将 ECX 寄存器循环 16 位,使低16 位到同一个寄存器的高 16 位,反之亦然,最后将 ECX 的低 16 位移动到 ES。

int open(char * nombre, unsigned char modo)

  int retval;
  // numero servicio 6
  // nombre del fichero a abrir (ES:BX) y modo (AL) de apertura
  asm("mov $6,%%ah \n\t"
      "mov %%cx,%%bx \n\t"
      "rol $16,%%ecx \n\t"
      "mov %%cx,%%es \n\t"
      "int $0x22 \n\t"
      "mov %%eax,%0 \n\t"
      : "=r"(retval)
      : "a"(modo), "c"(nombre)
  );
  return retval;       

【讨论】:

【参考方案3】:

GCC 是 32 位编译器。这也意味着,您应该最有可能尝试摆脱 es:bx 类型指针算法并转移到平面 32 位寻址(其中 cs=ds=es=0 的基数和每个段限制为 0xffffffff)。

在保护模式的用户空间访问状态寄存器很可能会出现访问冲突异常。

另外,什么是操作系统,允许 int 22h 以及它期望 es:bx 输入的位置?在 MS-DOS 中不应该调用它,因为它只是用作静态变量来恢复其他中断向量。

【讨论】:

我正在编写一个名为 OSO 的微型操作系统的小内核,它使用了 fat12 文件系统和 16 位 CPU 架构等旧技术。 int22h 是为我的内核制作的,我已经有一个中断例程。

以上是关于gnu 内联汇编错误的主要内容,如果未能解决你的问题,请参考以下文章

GNU g++ 内联汇编块,如 Apple g++/Visual C++?

最牛X的GCC 内联汇编

最牛X的GCC 内联汇编

帮助理解 x86 内联汇编中的 DIV 指令

初学者内联汇编分段错误

内联汇编,错误