简体   繁体   English

我正在Linux上学习汇编语言,[]符号使我感到困惑。 (NASM)

[英]I'm learning assembly on linux, and [] notation is confusing me. (NASM)

I'm working with the following code: 我正在使用以下代码:

section .text
    global _start
_start:
    mov ebx, testing
    mov [ebx], byte 0x4A
    add ebx, byte 1
    mov [ebx], byte 0x4B
    add ebx, byte 1
    mov [ebx], byte 0x4C

    ;sets var1 as '*'
    mov eax, 0x2A
    mov [var1], eax

    ;sets var2 as 'N'
    mov eax, 0x4E
    mov [var2], eax

    ;sets var3 = var2
    mov eax, [var2]
    mov [var3], eax

    ;Prints var1
    mov eax, 4
    mov ebx, 1
    mov ecx, var1
    mov edx, 1
    int 0x80

    ;Jumps a line
    mov eax, 4
    mov ebx, 1
    mov ecx, line_break
    mov edx, 2
    int 0x80

    ;Prints var2
    mov eax, 4
    mov ebx, 1
    mov ecx, var2
    mov edx, 1
    int 0x80

    ;Jumps a line
    mov eax, 4
    mov ebx, 1
    mov ecx, line_break
    mov edx, 2
    int 0x80

    ;Prints var3
    mov eax, 4
    mov ebx, 1
    mov ecx, var3
    mov edx, 1
    int 0x80

    ;Jumps a line
    mov eax, 4
    mov ebx, 1
    mov ecx, line_break
    mov edx, 2
    int 0x80

    ;Prints variable
    mov eax, 4
    mov ebx, 1
    mov ecx, variable
    mov edx, 3
    int 0x80

    ;Jumps a line
    mov eax, 4
    mov ebx, 1
    mov ecx, line_break
    mov edx, 2
    int 0x80

    ;Prints testing
    mov eax, 4
    mov ebx, 1
    mov ecx, testing
    mov edx, 3
    int 0x80

    ;Jumps a line
    mov eax, 4
    mov ebx, 1
    mov ecx, line_break
    mov edx, 2
    int 0x80


    ;Finishes program
    mov eax, 1
    mov ebx, 1
    int 0x80

section .data
    variable times 3 db 0x2A
    line_break dw 0x0D0A

section .bss
    testing resb 3
    var1 resb 1
    var2 resb 1
    var3 resb 1

It prints out: 它输出:

*
N
N
***
JKL

What i don't understand is: why in the first line "mov ebx, testing" there is no brackets arround "testing" and why those brackets are present in [var2] in the line "mov eax, [var2]". 我不明白的是:为什么在第一行“ mov ebx,testing”中没有括号“ testing”,以及为什么这些括号出现在“ mov eax,[var2]”行的[var2]中。 How exactly does this notation work? 这种表示法是如何工作的? Shouldn't [var2] be the effective address of var2? [var2]不应该是var2的有效地址吗?

The brackets around an identifier indicates that the value should be used as a pointer. 标识符周围的方括号表示该值应用作指针。 So without the brackets: 因此,没有括号:

mov ebx, testing

moves the address of testing into the eax register, where testing 地址移到eax寄存器中

mov eax, [var2]

moves the value pointed to by var2 into eax . 将var2指向的移动到eax

why in the first line "mov ebx, testing" there is no brackets arround "testing" 为什么在第一行“ mov ebx,测试”中没有方括号“测试”

The code in your question is written in NASM syntax. 您问题中的代码是用NASM语法编写的。 There are other x86 assemblers that use a slightly different syntax (eg MASM and TASM). 还有其他x86汇编器使用略有不同的语法(例如MASM和TASM)。

Anyway, mov ebx, testing means "place the address of testing in register ebx " . 无论如何, mov ebx, testing意味着“将testing地址放置在寄存器ebx That address is then used on the very next line, where the instruction mov [ebx], byte 0x4A writes the value 0x4A to the first byte pointed to by ebx (ie the first byte at testing ). 然后在下一行使用该地址,指令mov [ebx], byte 0x4A将值0x4A写入ebx指向的第一个字节(即, testing的第一个字节)。

In MASM/TASM syntax you would have written this as mov ebx, OFFSET testing . 在MASM / TASM语法中,您应该将其编写为mov ebx, OFFSET testing

why those brackets are present in [var2] in the line "mov eax, [var2]" 为什么这些括号出现在“ mov eax,[var2]”行的[var2]中

Because here you want to get the value at var2 , not var2 's address. 因为在这里您要获取var2的值,而不是var2的地址。 And in NASM syntax you do that using brackets, as in mov eax,[var2] . 在NASM语法中,您可以使用方括号来完成此操作,例如mov eax,[var2] In MASM/TASM syntax both mov eax,[var2] and mov eax,var2 would've read the value at var2 . 在MASM / TASM语法中, mov eax,[var2]mov eax,var2都将读取var2处的值。

Note that var1 , var2 and var3 are one byte each. 注意var1var2var3均为一个字节。 So trying to read and write 32-bit registers from/to those variables looks suspiciously like a bug. 因此,尝试从这些变量读取32位寄存器或向这些变量写入32位寄存器看起来像是一个可疑的bug。 You might want to change the declarations from resb 1 to resd 1 , or just read/write 8-bit registers from/to them. 您可能需要将声明从resb 1更改为resd 1 ,或仅从它们读取/ resd 1写入8位寄存器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM