定义标签的顺序重要吗?

问题描述 投票:0回答:1

我试图在汇编中创建一个简单的链表,但我意识到,如果我更改定义标签的顺序,代码将不会显示正确的结果。所以我在想,定义标签的顺序重要吗?或者在这个孤立的案例中顺序是否重要?

正确运行的代码:

%define OFFSET 8
%define SCALE 2

global _start

section .text

x1: 
    dq x2
    dq 48 ;; Zero

x2:
    dq x3
    dq 49 ;; One

x3:
    dq x4
    dq 50 ;; Two

x4:
    dq x5
    dq 51 ;; Three

x5:
    dq 0
    dq 52 ;; Four

end: 
    mov rax, 60
    mov rdi, 0
    syscall

_start:
    mov r8, 0

    .loop:
        mov rax, 1
        mov rdi, 1
        lea rsi, [x1 + r8 * SCALE + OFFSET] 
        mov rdx, 1
        syscall
        
        cmp qword [x1 + r8 * SCALE], 0 
        jz end
        add r8, OFFSET
    jmp .loop    

无法正常工作的代码(我更改了x1位置):

%define OFFSET 8
%define SCALE 2

global _start

section .text

x2:
    dq x3
    dq 49 ;; One

x3:
    dq x4
    dq 50 ;; Two

x4:
    dq x5
    dq 51 ;; Three

x5:
    dq 0
    dq 52 ;; Four

x1: 
    dq x2
    dq 48 ;; Zero

end: 
    mov rax, 60
    mov rdi, 0
    syscall

_start:
    mov r8, 0

    .loop:
        mov rax, 1
        mov rdi, 1
        lea rsi, [x1 + r8 * SCALE + OFFSET] 
        mov rdx, 1
        syscall
        
        cmp qword [x1 + r8 * SCALE], 0 
        jz end
        add r8, OFFSET
    jmp .loop    

assembly x86-64 nasm
1个回答
0
投票

将评论总结为正确的答案:

定义标签的顺序重要吗?

不,记住标签本身的顺序并不重要

  • (之前的 NASM 版本 2.14)
    global
    标签声明必须出现在之前相应标签的定义,并且
  • 本地标签定义简写 (
    .my_local_label
    ) 是相对于最新的全局标签。

[...]如果我更改定义标签的顺序,[...]我更改了x1位置[...]

是的并且您还移动了

dq
数据。 有两个更改,而不仅仅是移动标签位置。 就像您写下指令的顺序很重要一样,任何其他数据的顺序也很重要。 文本顺序(所有属于一个
section
)定义了内存中的顺序

我正在尝试在程序集中创建一个[单]链接列表[...]

正如 Jason Harper 所强调的,单链表意味着存储和检索(有效负载,指针)元组并遵循地址

pointer
指示。

        lea rsi, [x1 + r8 * SCALE + OFFSET] 

这是用于访问数组数据结构的模式,即。 e.内存中“连续”的字节序列。 对于单链表,您需要从内存中检索内容并将刚刚检索到的数据的指针部分视为地址。 这看起来怎么样? mov rsi, x1 ; now `rsi` contains _the address_ the label `x1` points to mov rcx, [rsi + 0] ; retrieve 8 Bytes located at `rsi` mov rsi, [rsi + 8] ; retrieve 8 Bytes located at `rsi + 8`

现在
rcx
包含

x1

处的前八个字节(即指针部分),所以如果你
使用
它的值
mov rcx, [rcx]

您已
跟随
指针。 在此指令之后,

rcx包含在x1

项指向的内存位置找到的内容(假设它不是空指针)。
我将让您将所有内容整齐地包裹成一个循环。
        cmp qword [x1 + r8 * SCALE], 0 
        jz end

rcx
是一个很好的寄存器来存储指针,因为这样您就可以使用

jrcxz

(如果 
rcx
 为零则跳转)指令。

© www.soinside.com 2019 - 2024. All rights reserved.