理解汇编语言中的指针

Understanding pointers in assembly language

我们是否将变量或寄存器括在括号中以指定汇编中的指针?

示例 1;

    MOV eax, array+4
    LEA eax, [array+4]

示例 2;

section .data
    array DB 116,97

section .bss
    variable RESB 0

section .text
    global _start:

_start:
    mov eax,[array]

    ;exit
    mov eax,1
    int 0x80

我在编译或 运行 上面的代码时没有收到任何错误。 EAX寄存器中是否放置数组的零索引地址?

示例 3;

    INC [variable]

编译上述代码时,出现“未指定操作大小”错误。为什么命令不能用作 INC variable?

示例 4;

section .data
    array DB 116,97

section .bss
    variable RESB 97

section .text
    global _start:

_start:
    mov eax,4
    mov ebx,1
    mov ecx,variable
    mov edx,1
    int 0x80

    ;exit
    mov eax,1
    int 0x80

此代码无效。

Are we enclosing the variable or registrar in brackets to specify a pointer in assembly?

Example1;

MOV eax, array+4
LEA eax, [array+4]

方括号就像 C 中的取消引用运算符 (*ptr)。他们在方括号内的结果地址处获取值。至于这个例子,这两个本质上做同样的事情。第一个将 array 标签的地址 + 4 移动到 eax 中。第二个使用 lea,加载其源操作数的有效地址。所以你得到 array + 4,取消引用它,然后用 lea 再次得到地址并将它加载到 eax.

Example2;

section .data
    array DB 116,97

section .bss
    variable RESB 0

section .text
    global _start:

_start:
    mov eax,[array]

    ;exit
    mov eax,1
    int 0x80

I am not getting any errors while compiling or running the above code. Is the address of the zero index of the array placed in the eax register?

有点。由于您要将它移动到 eax,一个 32 位寄存器,因此假设您要将地址 array 的前 4 个字节移动到 eax。但是在array处只有2个字节:11697。所以这可能不是你想要的。要将 array 处的第一个字节加载到 eax,请执行 movzx eax, BYTE [array],这会将 array[0] 移动到 eax 的 LSByte 并将较高字节清零。 mov al, [array] 也可以工作,但它不会将高位字节清零。

Example3;

INC [variable]

When compiling the above code, I am getting the "operation size not specified" error. And why can't the command be used as INC variable.

错误说明了一切。 variable 只是一个地址。当您使用 [] 时,它应该占用多少字节?您需要指定尺寸。例如,要获取第一个字节,您可以执行 inc BYTE [variable]。但是,从前面的示例来看,您似乎没有在 variable 处保留任何内容,因此尝试访问其中的任何字节可能会导致一些问题。至于“为什么不能将命令用作INC variable”,正如我刚才所说,variable只是一个转换为某个地址的标签。您无法更改 variable 转换成的地址。

Example4;

section .data
    array DB 116,97

section .bss
    variable RESB 97

section .text
    global _start:

_start:
    mov eax,4
    mov ebx,1
    mov ecx,variable
    mov edx,1
    int 0x80

    ;exit
    mov eax,1
    int 0x80

And this code is not working.

它可能看起来没有打印任何东西,但实际上是。 .bss 零初始化您保留的任何内存。这意味着当您在 variable 处打印第一个字节时,它只会打印 NUL 字符。但是打印的时候好像看不到,好像什么都没打印一样。

(顺便说一下,你确定你知道 resb 是做什么的吗?在一个例子中,你保留了 0 个字节,而在另一个例子中,你无缘无故地保留了 97 个字节。你可能想要再看看 resb 实际做了什么。)

array            ; variable address
byte[array]      ; value of first byte of array
word[array]      ; value of first word of array
byte[array + 1]  ; value of second byte of array

将变量名视为指针,使用 size[name] 获取指向的值(类似于 C 中的 *name,其中 name 是指针)