Assembly 这是什么意思;。“对齐”;x86汇编指令到底做什么?

Assembly 这是什么意思;。“对齐”;x86汇编指令到底做什么?,assembly,x86,memory-alignment,gnu-assembler,Assembly,X86,Memory Alignment,Gnu Assembler,我将列出我不明白的部分,并向您展示我不明白的部分 首先 .Align指令 .对齐整数,填充。 .align指令使生成的下一个数据按整数字节对齐 1.~?:“意味着什么导致生成的下一个数据以整数字节对齐?”我可以推测生成的下一个数据是要进行寄存器传输的内存,不是吗?模意味着除法的剩余部分。我不理解“将以整数字节模对齐” 简单数据声明的剩余部分是什么?由剩余部分对齐生成的下一个数据如何有用?如果下一个数据是模对齐的,也就是说,下一个生成的数据,不管它的确切含义是什么,是整数的余数吗?这完全没有道理

我将列出我不明白的部分,并向您展示我不明白的部分

首先

.Align指令

  • .对齐整数,填充。 .align指令使生成的下一个数据按整数字节对齐
  • 1.~?:“意味着什么导致生成的下一个数据以整数字节对齐?”我可以推测生成的下一个数据是要进行寄存器传输的内存,不是吗?模意味着除法的剩余部分。我不理解“将以整数字节模对齐”

    简单数据声明的剩余部分是什么?由剩余部分对齐生成的下一个数据如何有用?如果下一个数据是模对齐的,也就是说,下一个生成的数据,不管它的确切含义是什么,是整数的余数吗?这完全没有道理

    对于从C
    char
    编译的数据字节,x86中发出的.align指令(例如,
    .align 8
    指令)具体是什么,即
    char CHARACTER=0是为了什么?或者直接用该指令专门编码,而不是编译C后的初步汇编代码?我在汇编中调试过,注意到任何C/C++数据声明,如
    chars
    ints
    floats
    等,都将插入指令
    。将8
    与它们中的每一个对齐,并添加其他指令,如
    .bss
    .zero
    .globl
    .text
    .Letext0
    ,等等,
    .Ltext0


    所有这些指令是为了什么,或者至少是我的主要问题?我已经学习了很多主要的x86汇编指令,但从未被介绍或指出所有这些奇怪的指令。它们是如何影响操作码的,并且它们都是必需的?

    如注释中所述,这意味着编译器将添加足够的填充字节,以便下一个数据位于“偶数”位置(可被对齐值整除)。这一点很重要,因为对齐内存访问比未对齐内存访问快得多。(从0x10000加载双字优于从0x10001加载双字)。如果您正在与其他组件进行接口,并且需要发送/接收具有给定填充/对齐方式的数据结构,则它可能也很有用。

    模是指算术中的模运算,即c中的
    %
    符号,或者换句话说是“余数”

    “模n”通常意味着
    n
    表达式的模等于0。如果要放置地址“模4”,这意味着(地址%4)==0,这对于以下示例是正确的:0,4,8,0xC、0x10等


    硬件限制要求某些数据类型按大整数对齐。例如,某些DMA引擎可能需要模64。

    执行
    align
    指令的主要原因是为了加快执行速度。如果
    调用
    jmp
    目标位于奇数地址,则可能需要额外的总线传输和/或精确字节的提前。数据也是如此。在旧的80386手册中,当目标未对准时,某些操作码会受到惩罚

    我在手册里找到的‎) 第24页:

    Such misaligned data transfers reduce performance by requiring extra memory
    cycles. For maximum performance, data structures (including stacks) should
    be designed in such a way that, whenever possible, word operands are aligned
    at even addresses and doubleword operands are aligned at addresses evenly
    divisible by four. Due to instruction prefetching and queuing within the
    CPU, there is no requirement for instructions to be aligned on word or
    doubleword boundaries. (However, a slight increase in speed results if the
    target addresses of control transfers are evenly divisible by four.)
    

    首先,请注意,
    .align
    它不是一个特定于x86的概念,而是一个记录在案的GNU GAS指令。它也可以用于其他体系结构。x86不指定指令,只指定指令

    现在,让我们一起来理解它:

    a、

    编译和反编译:

    as -o a.o a.S
    objdump -Sd a.o
    
    输出:

    0000000000000000 <a-0x10>:
       0:   01 0f                   add    %ecx,(%rdi)
       2:   1f                      (bad)  
       3:   44 00 00                add    %r8b,(%rax)
       6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
       d:   00 00 00 
    
    0000000000000010 <sym>:
      10:   02                      .byte 0x2
    
    给出:

    0000000000000000 <sym-0x8>:
       0:   00 00                   add    %al,(%rax)
       2:   00 00                   add    %al,(%rax)
       4:   00 0f                   add    %cl,(%rdi)
       6:   1f                      (bad)  
        ...
    
    0000000000000008 <sym>:
       8:   02                      .byte 0x2
    
    0000000000000000:
    0:00添加%al,(%rax)
    2:00添加%al,(%rax)
    4:00 0f添加%cl,(%rdi)
    6:1f(坏)
    ...
    0000000000000008 :
    8:02.字节0x2
    

    所以这次
    sym
    被移动到
    8
    ,这是
    5
    之后的
    4
    的第一个倍数,这意味着汇编程序将把下一个字节放在一个可以被整数整除的地址,因此,如果最后一个字节放在
    0x0eda
    ,那么通常情况下,下,下一个字节将是plac在
    0x0edb
    处编译,但使用
    .align 8
    指令,下一个字节将被放置在
    0x0ec0
    处,下一个地址可以被8整除。注意。align用于汇编程序输出的任何内容,例如机器代码,而不仅仅是用于C中所称的“数据”我认为有些ISA中,
    .align
    .p2align
    (2的幂)的同义词,而不是
    .balign
    (字节).在x86上,它是
    .balign
    ,就像大多数其他汇编程序(如MASM和NASM)中的
    align
    指令一样。您介意将Trump从您的用户名中删除吗?因此用户名不是随机政治声明的好地方,尤其是与SO管理无关的声明。(而特朗普现在是一名普通公民,因此在这一点上,主张撤销禁令的理由越来越少,只是几个月前根本就不应该这么做。)@PeterCordes hi,相关元线程:请向mod报告或创建一个新线程,ping meAh,很公平,我接受更正。它们是允许的。我仍然不希望看到每个人的用户名变成政治声明,即使它们都是我同意的。(你会吗?也许你会。)因此,我认为它仍然有一些不太好的味道,如果你同意的话,你个人可能会考虑在这一点上自愿改变。哦,顺便说一下,报告<代码>。在x8664 MaOS/CLAN上的Alcune/Cuffy是<代码>的同义词。不应使用语法和。从0x10000加载双字优于加载双字f
    .skip 5
    .align 4
    sym: .byte 2
    
    0000000000000000 <sym-0x8>:
       0:   00 00                   add    %al,(%rax)
       2:   00 00                   add    %al,(%rax)
       4:   00 0f                   add    %cl,(%rdi)
       6:   1f                      (bad)  
        ...
    
    0000000000000008 <sym>:
       8:   02                      .byte 0x2