我想学习C语言的asm
一本书建议尝试实现此算法,这是一种非常简单的排序算法

begin
for i = 0 to len-1
    small = arr(i)
    index = i
        for j = i to len-1
            if ( arr(j) < small ) then
                small = arr(j)
                index = j
            end_if
        end_for
    arr(index) = arr(i)
    arr(i) = small
end_for
end_begin
我的代码的开头是(可以根据需要提供其余内容)
section .bss


section .data

len dq 5
array dq 1 , 3 ,  6 , 8 ,  2


section .text


        global _start

_start:
        mov rdi , [len]
        mov rsi , array
        call sort
        exit





sort:
        push rbp
        mov rbp,rsp
        push qword 0 ; i_counter = rbp-8
        push rdi ; len = rbp-16
        push rsi ; *array = rbp -24
        push  qword 0 ; j = rbp - 32
        dec qword [rbp-16]
i_loop:
        mov r8 , [rbp-16]
        cmp [rbp-8], r8 ; if counter = len - 1 (decreased above)
        je end_i_loop
        mov rbx , [rbp-8]
        mov rax , qword [  rbp-24 - rbx * 8] ; small = array(i) and line 38
        mov rcx , [rbp-8] ; index = i
        mov [rbp - 32 ] , rcx ; j = i
在第38行,我得到了错误
错误:有效地址无效
起初,我认为这是对齐错误(因此,sort函数开始处的push四字)
然后我尝试了movq指令(由于其他原因,该指令显然不起作用,因为我已经阅读了指令手册)
即使被寄存器引用(至少是mov [rax],qword [rbp-24-rbx * 8]编译),向内存地址移动似乎也可以,但是这样做几乎没有意义。
我可能会用lea来修复它,它会编译,但是我想要这个值,不mov rax,qword [rbp-24-rbx * 8]给出了rbp-24-rbx * 8指向的值吗?
由于我在代码中的四个不同点(第38行之后)都遇到相同的问题,因此我完全陷入了困境,不知道现在要尝试什么
有人可以解释为什么它不能编译,并在可能的情况下给出解决方案(或至少提示)

最佳答案

mov rax , qword [  rbp-24 - rbx * 8]
从表面上看这是非法的,因为SIB寻址模式只能添加缩放的索引寄存器(此处为rbx * 8)。它不能减去它。但是,如果您想要array(i),则无论如何都要添加它,因为此处的rbx对应于i
但是,似乎您正在尝试使用存储在rbp-24中的指针作为基址,并且也不支持该指针;基址必须来自寄存器。方便地,您已经在array寄存器中有了rdi的地址,所以我认为您想要的只是
mov rax, qword [rdi + rbx * 8]
只是改善代码的一般提示:完全使用汇编语言的主要原因是速度,而达到速度的最重要方法是最小化内存访问。您确实不希望将局部变量保留在堆栈中,并且每次触摸它们时都访问内存。机器有很多寄存器,因此只需为每个变量选择一个寄存器并将其保存在那里。
如果您一直试图通过读取未优化的编译器程序集输出来学习,则可能会养成过度使用内存的习惯。非优化的编译器会将所有内容保留在堆栈中,因此它具有一致的位置和一致的地址(如果需要)。但是尝试启用优化,您会发现所有这些魔术都消失了,并且尽可能多地使用寄存器完成了所有工作。这是您应该努力争取的更多东西。

关于linux - 无法理解: invalid effective address on mov rax , qword [ rbp-24 - rbx * 8]错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64563796/

10-10 22:43