汇编中的指令对齐



title: 汇编中的指令对齐

tags: ARM

date: 2018-10-23 20:50:39

---

汇编中的指令对齐

搜索下官方文档的索引.align,有如下描述,也就是有两种情况,对于ARM,表示的是末尾几个0,也就是2^x了.具体填充格式可以指定align abs-expr, abs-expr, abs-expr参考链接

For other systems, including ppc, i386 using a.out format, arm and strongarm, it is the number of low-order zero bits the location counter must have after advancement. For example ‘.align 3’ advances the location counter until it a multiple of 8. If the location counter is already a multiple of 8, no change is needed.

当在代码中定义了字符串之后,可能会出现代码指令非4字节对齐的情况,如下:reset的指令在30000045的位置,显然有问题,使用aligin来保持对齐

 //
 und_string:
       .string "undefined instruction exception-"
  reset:
 //-------------------------------------------------------------
 30000024 <und_string>:
  22 30000024:   65646e75    strvsb  r6, [r4, #-3701]!
  23 30000028:   656e6966    strvsb  r6, [lr, #-2406]!
  24 3000002c:   6e692064    cdpvs   0, 6, cr2, cr9, cr4, {3}
  25 30000030:   75727473    ldrvcb  r7, [r2, #-1139]!
  26 30000034:   6f697463    swivs   0x00697463
  27 30000038:   7865206e    stmvcda r5!, {r1, r2, r3, r5, r6, sp}^
  28 3000003c:   74706563    ldrvcbt r6, [r0], #-1379
  29 30000040:   2d6e6f69    stccsl  15, cr6, [lr, #-420]!
  30     ...
  31
  32 30000045 <reset>:
  33 30000045:   e3a00453    mov r0, #1392508928 ; 0x53000000
  • 使用align 4 之后对齐在3000,005032 30000050 <reset>:
  • 使用align 5之后 对齐在3000006030000060 <reset>:

    写一个demo测试一下,发现.align x对齐的是2^x字节,uboot对齐的是align 5,也就是32字节

    _start:
         .string "1234"
    _test_addr:
        ldr r0,[r2]
    反汇编如下
    00000000 <_start>:
    00000005 <_test_addr>:
    //---------------------------------------------------
    _start:
         .string "1234"
    .align 4
    _test_addr:
        ldr r0,[r2]
    反汇编如下
    00000000 <_start>:
    00000010 <_test_addr>:
    //---------------------------------------------------
    _start:
         .string "1234"
    .align 5
    _test_addr:
        ldr r0,[r2]
    反汇编如下
    00000000 <_start>:
    00000020 <_test_addr>:

原文地址:https://www.cnblogs.com/zongzi10010/p/9840190.html

时间: 2024-10-08 01:31:36

汇编中的指令对齐的相关文章

汇编中Enter与Leave指令

Enter的作用相当==push ebp和mov ebp,esp 这后面两句大家很熟悉吧?函数开始一般都是这两句 Leave的作用相当==mov esp,ebp和pop ebp 而这后面这两句也很常见,函数调用完后一般的用到 以上的Enter和leave的作用分别函数开始和结束 Win32汇编中局部变量的使用方法可以解释一个很有趣的现象:在DOS汇编的时候,如果在子程序中的push指令和pop指令不配对,那么返回的时候ret指令从堆栈里得到的肯定是错误的返回地址,程序也就死掉了.但在Win32汇

汇编中的跳转指令

能修改CS以及IP的指令都是转移指令.它分为段内转移,段间转移. 段内转移:只修改IP的值 段间转移:同时修改CS以及IP的值 段内转移根据转移的距离远近分为:短转移,近转移 短转移:转移范围为-128 – 127 近转移:转移范围为-32768 –32767 根据转移情况又分为: 无条件转移指令 条件转移指令 循环指令 过程 中断 <1> jmp short xxx(行号) 这个是短转移指令,实现段内的转移,在翻译成机器码的时候,码内并没有目标地址,有的只是转移位移,这样做的好处就是防止目标

为什么X86汇编中的mov指令不支持内存到内存的寻址?

在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了???这个问题在stack overflow有个解释不错: The answer involves a fuller understanding of RAM. Simply stated, RAM can only be in two states, read mode or write mode.

C/C++中的内存对齐问题和pragma pack命令详解

这个内存对齐问题,居然影响到了sizeof(struct)的结果值.突然想到了之前写的一个API库里,有个API是向后台服务程序发送socket请求.其中的socket数据包是一个结构体.在发送socket之前,会检测数据的长度:服务端接收到数据后也会检测长度.如果说内存对齐问题影响到了结构体的sizeof,那么socket发送结构体的时候,是怎么发送的?发送的内容中是否包含结构体中的“空洞”?如果API库中的对齐方式没有设定,那么服务端和客户端的sizeof结果将不同,这会引起很多问题吗? 下

16位汇编中的伪指令

汇编中的伪指令(基于汇编编译器MASM讲解) 一丶什么是伪指令,以及作用 首先我们用汇编开发效率低,如何才能开发效率高,甚至开发速度比C语言或这个高级语言快 答案: 伪指令 什么是伪指令 伪指令是汇编编译器提供的,比如昨天我们写的汇编代码,假设调用一个Call我们每次都要手工处理 保存栈底,开辟就变量空间,保存寄存器环境....每次都要做,特别麻烦,所以编译器帮我们提供了伪指令,只要我们 按照汇编编译器的语法去写,那么这些汇编编译器则会自动帮我们补全 比如昨天的代码: ;调用开始,把参数压栈 m

汇编中,BP,SP有何区别?分别怎么使用?

bp寄存器,跟其它什么BX,AX一样的用法, SP是用在栈上的,配合SS使用,像SS:SP SS上放段地址,SP上放偏移地址. 寻址时,像[bp],相当于SS:[bp] 就是说它默认使用SS 像BX默认使用CS---------------------------------------------------ss栈段寄存器sp栈顶指针寄存器bp默认的栈寻址寄存器--------------------------------------------------- sp会随着带有堆栈操作的指令(

汇编中的命令

-r 查看当前寄存器的状态, -r 寄存器x 可以改变寄存器x的值. -d 可以查看内存 三种使用方法:1.-d显示之后128个字节 2.-d 段地址:偏移地址,从这段地址开始后的128字节 3.-d 段地址:偏移地址  偏移地址,显示两个地址间的字节. -u 和-d用法一样,不过是查看字节对应的汇编指令 -e 向内存中写入指令 三种用法:1.-e改变当前cs:ip之后的内存 2.-e 段地址:偏移地址  需要改变的内容(前面都是输入) 3.-e段地址:偏移地址[enter]         

汇编中精妙的流程控制

汇编中精妙的流程控制 前言 今天一天挺废啊,百无聊赖啊,唉,也不想学习,看了一天的电视了,不过好在我还是想看看OS中的东西,这次咱们一起来看看一个特别有趣的内容,就是汇编级的语言,如何利用寄存器实现if/for/while这些高级语言的流程控制,这一点十分神奇.保证你绝对想不到在汇编中是这样实现平时的流程控制的. 正文 条件码寄存器 这个子标题在之前就出现过,条件码寄存器与普通的寄存器不同,他们都是1位寄存器,换句话说,它们当中的值只有0和1.当有算数与逻辑发生时,这些条件码寄存器当中的值会相应

C语言中的字节对齐以及其相关处理

首先,我们来了解下一些基本原理: 一.什么是字节对齐一个基本类型的变量在内存中占用n个字节,则该变量的起始地址必须能够被n整除,即: 存放起始地址 % n = 0,那么,就成该变量是字节对齐的;对于结构体.联合体而言,这个n取其所有基本类型的成员中占用空间字节数最大的那个;内存空间是以字节为基本单位进行划分的,从理论上讲,似乎对任何类型的变量的访问都可以从任何地址处开始,但实际情况是在访问特定类型变量的时候经常是从特定的内存地址处开始访问,这就需要各种类型的数据只能按照一定的规则在空间上排列,而