.align 就是用来对齐的,究竟怎么对齐,有啥情况?下面分析一下

基本情况讲解

(一)

$vim align1.s

在新建的文件编辑以下代码:

1
2
3
4
5
6
_start:
b reset
.byte 0x55
.byte 0xaa
reset:
ldr r0, =0x53000000

保存后,执行如下命令:

1
$arm-linux-as align1.s -o align1.o

这样的话有的编译器可能会报错,但我的编译器没有报错,虽然没有报错,但反汇编的结果显示,运行时肯定会出问题。

执行如下命令(进行反汇编):

1
$arm-linux-objdump -d align1.o

显示如下:

1
2
3
4
5
00000000 <_start>:
0: ea000000  b  4  <_start+0x4>
4: 0453aa55  ldreqb s1, [r3], -#2645
00000006 <reset>:
6: e3a00453  mov r0, #1392508928 ; 0x53000000

很明显,跳转语句应该跳到0x06处,而它却跳到0x04处,我们分析一下。首先,ARM指令都是32位的,这里要求4字节(一个word)对 齐,b reset 指令占了4个字节,接着我们用 .byte 指令定义2个常数,因为这里是 byte 类型,所以只占了八位,两个数据,一共占16位。由于连接器内部有一个程序地址计数指针,里面保存着当前的地址,这地址指针是连接器内部工作需要的,我们 不需要理会,只需要了解有这么一个机制。假如_start从0x00,第一条指令占4个byte,然后连续分配2个byte,当前地址指针应该是 0x06,那么问题来了,下条指令,也就是标号 reset 处的ldr指令,是一条ARM指令,这要求是 4个字节对齐的,当前的地址为 0x06,并不能满足这个要求,所以编译器自动将地址指针跳到0x04。

 

解决办法很简单,我们只需要加一条 .align 指令,问题就解决了

1
2
3
4
5
6
7
_start:
b reset
.byte 0x55
.byte 0xaa
.align
reset:
ldr r0, =0x53000000

编译结果是:

1
2
3
4
5
00000000 <_start>:
0: ea000000  b 8 <reset>
4: 0000aa55  andeq sl, r0, r5, asr sl
00000008 <reset>:
8: e3a00453  mov r0, #1392508928 ; 0x53000000

在两个 .byte 指令后自动补零,直到满足地址要求为止。这里就是将地址累加到 0x08符合ARM指令要求,所以在这里写入下条指令。

这是基本内容,下面研究一下其他情况

(二).align 5

这里只是一个例子,重点想说的是 这个 .align 5 后面的 5 究竟是什么意思? uboot里面就有这指令。我们继续做做试验,看看编译结果是什么

1
2
3
4
5
6
7
8
9
10
11
12
_start:
b reset
 
.align 5
.byte 0x55
 
.align 5
.byte 0xaa
 
.align
reset:
ldr r0, =0x53000000

编译结果:

1
2
3
4
5
6
7
8
00000000 <_start>:
0: ea00000f  b 44 <reset>
...
20: 00000055  andeq r0, r0, r5, asr r0
...
40: 000000aa  andeq r0, r0, sl, lsr #1
00000044 <reset>:
44: e3a00453  mov r0, #1392508928 ; 0x53000000

我们发现这编译结果有点意思,这地址分配一下子上去了,但是也不难,分析一下就OK,看那个 20 和 40 ,这里是十六进制,也就是 32 和 64了。那么很容易可以联想到,这里做的是幂运算,也就是 .align 5 对齐的地址为 2^5 = 32,之前的地址全部补零。

(三).balignl 16,0xdeadbeef

1
2
3
4
5
6
7
_start:
b reset
 
.balignl 16,0xdeadbeef
 
reset:
ldr r0, =0x53000000

在看uboot的时候还有这么一个语句,查了半天as的手册才找到,囧,不过稍微做了一下实现,觉得又不是很难,我们看看结果:

1
2
3
4
5
6
7
00000000 <_start>:
0: ea000002  b 10 <reset>
4: deadbeef  cdple 14, 10, cr11, cr13, cr15, {7}
8: deadbeef  cdple 14, 10, cr11, cr13, cr15, {7}
c: deadbeef  cdple 14, 10, cr11, cr13, cr15, {7}
00000010 <reset>:
10: e3a00453  mov r0, #1392508928 ; 0x53000000

可以看出,这指令就是将 deadbeef字符串填进去,一共填到地址为16对齐的地方为指,上面可以看到,这里填到 0x10 也就是 16了。

细说align 的作用及用法的更多相关文章

  1. serialVersionUID, ObjectInputStream与ObjectOutputStream类,Serializable接口,serialVersionUID的作用和用法

    ObjectInputStream与ObjectOutputStream类所读写的对象必须实现Serializable接口,对象中的transient和static类型成员变量不会被读取和写入 Ser ...

  2. Oracle函数over(),rank()over()作用及用法--分区(分组)求和& 不连续/连续排名

    (1)   函数:  over()的作用及用法:    -- 分区(分组)求和. RANK ( ) OVER ( [query_partition_clause] order_by_clause )D ...

  3. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

  4. JSP九大内置对象的作用和用法总结?

    JSP九大内置对象的作用和用法总结? 1.request对象javax.servlet.http.HttpServletRequest request对象代表了客户端的请求信息,主要用于接受通过HTT ...

  5. (转载)MySQL数据类型中DECIMAL的作用和用法

    (转载)http://database.51cto.com/art/201005/201651.htm 在MySQL数据类型中,例如INT,FLOAT,DOUBLE,CHAR,DECIMAL等,它们都 ...

  6. PreTranslateMessage作用和用法

    PreTranslateMessage作用和用法  PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗体的消息都要通过这里,比較经常使用, ...

  7. ViewHolder的作用和用法

    一直都看别人用ViewHolder,自己也用过,却不知道它的作用是什么?但知道肯定很有用,而且现在android studio应该有直接生产Viewholder的插件, 不过博主我是个新手,就没尝试去 ...

  8. Oracle分析函数及常用函数: over(),rank()over()作用及用法--分区(分组)求和& 不连续/连续排名

    (1)   函数:  over()的作用及用法:    -- 分区(分组)求和. sum() over( partition by column1 order by column2 )主要用来对某个字 ...

  9. og标签对SEO的作用及用法

    meta property=og标签对SEO的作用及用法,如果你仔细观察会发现本站点<head>代码中有一段:"property="og:image"这段代码 ...

随机推荐

  1. CentOS7关于网络的设置

    装好CentOS7后,我们一开始是上不了网的 这时候,可以输入命令dhclient,可以自动获取一个IP地址,再用命令ip addr查看IP 不过这时候获取的IP是动态的,下次重启系统后,IP地址也会 ...

  2. LoadBitmap(IDB_BITMAP1) -- 未定义标识符 IDB_BITMAP1

    错误原因:1:头文件没有加入 #include"resource.h" 2:没有导入该资源或者资源ID错误

  3. BZOJ4725: [POI2017]Reprezentacje ró?nicowe

    $n \leq 1e5$,$x \leq 1e9$. 1e9呵呵,暴力处理$a_n$的前几项直到1e9.然后处理出差的数列,每次在这里面找,找得到就回答,找不到,那有贡献的只有$a_i-a_{i-1} ...

  4. 蜥蜴 BZOJ 1066

    蜥蜴 [问题描述] 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距 ...

  5. KJ面试

    1.css input checkbox和radio样式美化 <span class="pay_list_c1 on"> <input type="ra ...

  6. AC日记——砝码称重 洛谷 P2347

    题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1g砝码有a1个,2g砝 ...

  7. python的websocket实现Tornado

    1.使用flask的扩展: pip install flask-socketio 2.Tornado提供较好的ws(websocket)支持 参考:1.http://www.jianshu.com/p ...

  8. csu1527: Bounty Hunter

    Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status id=134 ...

  9. Linux网络编程简单示例

    linux 网络编程是通过socket(套接字)接口实现,Socket是一种文件描述符,socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭& ...

  10. C++与Java语法上的不同

    最近学习算法和刷题基本都是用C++写的程序,在这个过程中,发现C++和Java在语法上有很多相同点,但也有很多不同点,而这些不同点对于已经掌握Java的程序员来说,理解C++代码可能会有些吃力甚至困难 ...