【问题标题】:asm error message: `(%rax,%edx,4)' is not a valid base/index expressionasm 错误消息:`(%rax,%edx,4)' 不是有效的基本/索引表达式
【发布时间】:2011-11-28 02:50:14
【问题描述】:

:96: 错误:`(%rax,%edx,4)' 不是有效的基/索引表达式

line97: 错误: `-4(%rax,%edx,4)' 不是有效的基础/索引表达式

line101: 错误: `(%rax,%edx,4)' 不是有效的基础/索引表达式

line102: 错误: `-4(%rax,%edx,4)' 不是有效的基础/索引表达式

我收到这些错误消息,但不知道如何解决。

这是我的代码:

   

__asm__ (

           "loop:       \n\t"
           "movl        $1,%3\n\t"
           "movl        $0, %6\n"

           "start:        \n\t"

           "movl        (%1,%3,4),%4\n\t"       
           "movl        -4(%1, %3, 4), %5\n\t"

           "cmpl        %4, %5\n\t"           
           "jle         next\n\t"

           "xchgl        %4, %5\n\t"               
           "movl        %4, (%1, %3, 4)\n\t"        
           "movl        %5, -4(%1, %3, 4)\n\t"        
           "movl        $1, %6\n\t"

           "next:       \n\t"
           "incl        %3  \n\t"        

           "cmpl        %3, %2\n\t"
           "jge        start\n\t"        

           "cmpl        $0, %6\n\t"
           "je        end\n\t"

           "jmp        loop\n\t"        
           "end:        \n\t"

请帮助解释如何修复这些错误消息。 我正在尝试在 ASM 中进行冒泡排序。

【问题讨论】:

  • 你为什么不重新格式化你的代码?
  • ppl 说不清楚,所以我试图清理它?
  • asm compile issue 的可能重复项

标签: gcc assembly 64-bit


【解决方案1】:

您没有说您的目标处理器是什么,但它似乎是 x64。在 x64 上,(%rax, %edx, 4) 不是合法组合。有关有效寻址模式的列表,请参阅处理器手册。我猜你的意思是(%rax, %rdx, 4)

【讨论】:

    【解决方案2】:

    您的问题最可能的原因是在 %3 操作数中使用了显式的 32 位整数类型。您尚未显示内联程序集的约束列表。但如果你这样做,就会出现上述情况:

    int main(int argc, char **argv)
    {
        int result, foobaridx;
    
        foobaridx = foobar[4];
    
        __asm__ (
            "       dec    %2\n\t"
            "       movl   (%1, %2, 4), %0\n\t"
        : "=r"(result) : "r"(foobar), "r"(foobaridx) : "memory", "cc");
    
        return result;
    }
    

    在 32 位模式下编译可以正常工作:

    $ gcc -O8 -m32 -c tt.c
    $ objdump -d tt.o
    
    tt.o:文件格式elf32-i386
    
    00000000 :
       0: 55 推 %ebp
       1: b8 00 00 00 00 移动 $0x0,%eax
       6: 89 e5 移动 %esp,%ebp
       8: 83 ec 08 sub $0x8,%esp
       b: 8b 15 10 00 00 00 移动 0x10,%edx
      11: 83 e4 f0 和 $0xfffffff0,%esp
      14: 12 月 4 日 %edx
      15: 8b 04 90 移动 (%eax,%edx,4),%eax
      18: 83 ec 10 sub $0x10,%esp
      1b: c9 离开
      1c: c3 ret

    但在 64 位模式下,编译器/汇编器不喜欢它:

    $ gcc -O8 -c tt.c
    /tmp/cckylXxC.s:汇编器消息:
    /tmp/cckylXxC.s:12: 错误: `(%rax,%edx,4)' 不是有效的基础/索引表达式

    解决此问题的方法是使用#include <stdint.h> 并将最终用于寻址(作为基址或索引寄存器)的寄存器操作数转换为uintptr_t(这是一个保证为'的整数数据类型大小兼容'到指针,无论你是在 32 位还是 64 位)。通过该更改,64 位编译成功并创建以下输出:

    $ gcc -O8 -c tt.c
    $ objdump -d tt.o
    
    tt.o:文件格式elf64-x86-64
    
    部分.text的反汇编:
    
    0000000000000000 :
       0: 48 63 15 00 00 00 00 movslq 0(%rip),%rdx #7
       7: b8 00 00 00 00 移动 $0x0,%eax
       c: 48 ff ca dec %rdx
       f: 8b 04 90 mov (%rax,%rdx,4),%eax
      12:c3 retq

    祝你的内联汇编“与 32/64 位无关”!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-17
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 2016-07-03
      • 1970-01-01
      相关资源
      最近更新 更多