Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 装配中的偏移是什么?如何使用它们?_Assembly_Arm - Fatal编程技术网

Assembly 装配中的偏移是什么?如何使用它们?

Assembly 装配中的偏移是什么?如何使用它们?,assembly,arm,Assembly,Arm,在下面的代码中,这个人将一个寄存器指向一个地址,我明白了。为什么后来他并没有将R3加载到R1中,为什么它必须被0x14偏移 R1是如何在几行代码中移动的,是什么使它这样做的?这真让我困惑,几个小时的搜索也没有给出明确的答案 密码是从这里偷来的 偏移量在汇编程序中用于访问数据结构 在您正在使用的代码中,您可以看到正在加载的基址。这是数据结构的起始地址 数据结构将在某个地方定义,但不在代码中定义。定义通常是一个表,例如显示 这个有4个字节 2个字节 4字节表示其他内容 等等 现代处理器使用这样

在下面的代码中,这个人将一个寄存器指向一个地址,我明白了。为什么后来他并没有将R3加载到R1中,为什么它必须被0x14偏移

R1是如何在几行代码中移动的,是什么使它这样做的?这真让我困惑,几个小时的搜索也没有给出明确的答案

密码是从这里偷来的


偏移量在汇编程序中用于访问数据结构

在您正在使用的代码中,您可以看到正在加载的基址。这是数据结构的起始地址

数据结构将在某个地方定义,但不在代码中定义。定义通常是一个表,例如显示

  • 这个有4个字节
  • 2个字节
  • 4字节表示其他内容
  • 等等
现代处理器使用这样的内存映射进行输入和输出。每个设备都“映射”到特定地址。这是代码中的基址


如果不知道什么硬件连接到处理器,我们就无法告诉您处理器中的数据结构

偏移量在汇编程序中用于访问数据结构

在您正在使用的代码中,您可以看到正在加载的基址。这是数据结构的起始地址

数据结构将在某个地方定义,但不在代码中定义。定义通常是一个表,例如显示

  • 这个有4个字节
  • 2个字节
  • 4字节表示其他内容
  • 等等
现代处理器使用这样的内存映射进行输入和输出。每个设备都“映射”到特定地址。这是代码中的基址


如果不知道什么硬件连接到处理器,我们就无法告诉您处理器中的数据结构

原因是它是实现预期效果的最短(最少指令)方式。有两件事正在做:(1)为输出配置端口,(2)切换输出。由于为了执行这些操作而需要写入的内存位置在附近,因此需要使用处理器的基址/偏移设施来解决这两个问题

下面的代码也可以达到同样的效果,但没有任何好处。它更大(不太可能适合固定存储),循环速度也不快(处理器在执行STR指令时仍需将R1中的新值加零)

my\u asm
; 设置指向端口1的基址的指针
LDR R1,=0x2009c020;指向端口1基的指针
LDR R3,=0x00040000;将LED 1端口引脚设置为输出
STR R3,[R1,#0x00];设置方向位(基+0x00)

LDR R1,=0x2009c034;指向端口1输出的指针原因是它是实现所需效果的最短(最少的指令)方式。有两件事正在做:(1)为输出配置端口,(2)切换输出。由于为了执行这些操作而需要写入的内存位置在附近,因此需要使用处理器的基址/偏移设施来解决这两个问题

下面的代码也可以达到同样的效果,但没有任何好处。它更大(不太可能适合固定存储),循环速度也不快(处理器在执行STR指令时仍需将R1中的新值加零)

my\u asm
; 设置指向端口1的基址的指针
LDR R1,=0x2009c020;指向端口1基的指针
LDR R3,=0x00040000;将LED 1端口引脚设置为输出
STR R3,[R1,#0x00];设置方向位(基+0x00)
LDR R1,=0x2009c034;指向端口1输出寄存器1的指针正在加载端口1的基址和第三条指令

STR     R3, [R1, #0x00]       ; set direction bits (base + 0x00)
…表明R1内容寻址的数据的第二个字节是端口1上LED的方向位

理论上,您可能可以在该指令完成后加载R1以寻址偏移量0x014处的数据,但这意味着您将包含一条额外的、不必要的指令。通常,如果您在汇编中编写某些内容,您会尝试尽可能高效地完成它

STR     R3, [R1, #0x14]       ; set outputs directly (base + 0x14)
从上面的代码中,您可以了解到,在与端口1相关的数据中,方向指示灯位于偏移量1处,而输出位于字节15(,我认为)。除此之外,我们没有任何信息

但是,如果您需要在稍后的过程中访问与端口1相关的任何其他数据,并且已经更新了基址寄存器,使其指向偏移量0x14,超过了端口1记录的开始,则必须加载该地址,或者重新加载基址并获取偏移量,特别是当它位于端口1的数据基址和偏移量14之间时

如果要处理特定的记录/数据段,则使用基址寄存器并对其进行偏移,而不是在每次需要时加载一个包含要更新的存储器中的直接地址的寄存器,这样效率更高

寄存器1正在加载端口1的基址和第三条指令

STR     R3, [R1, #0x00]       ; set direction bits (base + 0x00)
…表明R1内容寻址的数据的第二个字节是端口1上LED的方向位

理论上,您可能可以在该指令完成后加载R1以寻址偏移量0x014处的数据,但这意味着您将包含一条额外的、不必要的指令。通常,如果您在汇编中编写某些内容,您会尝试尽可能高效地完成它

STR     R3, [R1, #0x14]       ; set outputs directly (base + 0x14)
从上面的代码中,您可以了解到,在与端口1相关的数据中,方向指示灯位于偏移量1处,而输出位于字节15(,我认为)。除此之外,我们没有任何信息

但是,如果您需要在稍后的过程中访问与端口1相关的任何其他数据,并且已经更新了