14

由于这方面的网络资源很少,为了将来的搜索,我将首先列出 IA-32 汇编语言 (NASM) 的地址模式,然后回答一个简短的问题。

  1. 寄存器寻址
    • mov eax, ebx:将 ebx 中的内容复制到 eax
    • mov esi, var: 将 var 的地址(比如 0x0040120e)复制到 esi
  2. 立即寻址(第二个操作数是立即数)
    • mov bx, 20: 16位寄存器bx获取实际值20
  3. 直接内存寻址(通过指定地址直接从内存中加载)
    • mov ax, [1000h]:从地址 4096 的字节(十六进制的 0x1000)加载一个 2 字节的对象到一个名为“ax”的 16 位寄存器中
    • mov [1000h], ax: 地址1000h的内存获取ax的值
  4. 直接偏移寻址(同3,只是使用算术修改地址)
    • 移动,[byte_tbl+2]
  5. 间接寄存器(使用存储在寄存器中的地址访问内存)
    • mov ax, [di]:将 di 指定的内存地址处的值复制到 ax 中
    • mov dword [eax], var1: 将var1中的值复制到eax指定的内存槽中

请注意,以上内容适用于 NASM。对于 MASM/TASM,您将使用 "mov esi, OFFSET foo" 来获取地址,而 "mov esi, foo" 和 "mov esi, [foo]" 都将获取值(@Michael 的信任)。

所以,关于我的问题。它与以下教程第 29 页底部的示例有关:http ://www.tutorialspoint.com/assembly_programming/assembly_tutorial.pdf

它基本上列出了以下代码作为间接内存寻址的示例。

MY_TABLE TIMES 10 DW 0 ; Allocates 10 words (2 bytes) each initialized to 0 
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX 
MOV [EBX], 110 ; MY_TABLE[0] = 110 
ADD EBX, 2 ; EBX = EBX +2 
MOV [EBX], 123 ; MY_TABLE[1] = 123 

我的问题:

  1. “MOV EBX, [MY_TABLE]”实际上不应该是“MOV EBX, MY_TABLE”,因为我们想将表的地址放在 EBX 中,而不是值本身?
  2. 最后肯定是 MY_TABLE[2] 等于 123,而不是 MY_TABLE[1]?
4

2 回答 2

7
  1. 在 NASM 语法中,该指令应该是MOV EBX, MY_TABLE. 要做MOV EBX, [MY_TABLE]的是将位于的前 4 个字节加载MY_TABLEEBX. 另一种选择是使用LEA, 如LEA EBX, [MY_TABLE].

  2. 在这种情况下,教程是正确的。MY_TABLE被定义为一个单词数组。x86 上的一个字是 2 个字节,所以 的第二个元素MY_TABLE确实位于MY_TABLE + 2.

于 2013-12-16T11:15:34.053 回答
0

该教程甚至不是有效的 NASM 代码。有关吸引人的 x86 指南/资源/手册的链接,请参阅SO 上的 x86 标签 wiki 。

MOV [EBX], 110不会汇编,因为两个操作数都不意味着操作数大小。(我认为即使 MASM 也不会汇编它,但是像 emu8086 这样的一些糟糕的汇编器对于这样的指令有一个默认的操作数大小。) mov word [ebx], 110会做一个 16 位存储。

MOV EBX, [MY_TABLE]将组装,但它会从表中加载前 2 个单词。 mov ebx, MY_TABLE将地址放入寄存器。

于 2017-11-29T20:41:21.853 回答