11.汇编代码简单操作

摘要:
在与GNU交叉编译的工具链中使用汇编程序。下一步是实现汇编代码操作:保持不变1010。因此,最后输出0b101000。Cmp指令的操作与Txt指令的操作相同:因此cpsr的Z位设置为1。结果的高四位的值为4。跳转指令:5。所以它跳转到标签branch1执行。所以添加一个绑定以跳到结尾。从上面,我们可以看到lr存储bl返回后的下一个地址。将其分配给要跳转的PC指针。程序状态字访问指令。

11.汇编代码简单操作

11.汇编代码简单操作第1张

  1. 使用汇编的原因很简单,就是汇编代码的高效。在机器启动的时候,利用汇编的高效,对硬件进行初始化,为加载内核,提供条件。
  2. 目前常用的ARM汇编指令有两种:

    *ARM标准汇编:适用于ARM公司的汇编器,适合在Windows平台下使用。

    *GNU汇编:使用与GNU交叉编译工具链中的汇编器,适合于Linux平台开发。

3.汇编程序框架:注意下面的操作环境是Redhat 6.4 + eclipse C/C++ +CDT插件。

汇编代码的基本框架

11.汇编代码简单操作第2张

汇编用到的地方,启动代码,效率要求高效的地方。

上面是启动代码的框架。

下面搭建框架:

start.S:

.text

.global _start

_start:

    mov r2,#2

    mov r3,#3

Makefile:

all : start.o

    arm-linux-ld -Tgboot.lds -o start.elf $^

%.o : %.S

    arm-linux-gcc -g -o $@ $^ -c

clean:

    rm *.o *.elf

简单工程的运行的结构:

链接器脚本:

Gboot.lds:

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS {

    . = 0x50008000;

    

    . = ALIGN(4);

    .text :

    {

    start.o (.text)

    *(.text)

    }

    . = ALIGN(4);

    .data :

    {

    *(.data)

    }

    

    . = ALIGN(4);

    bss_start = .;

    .bss :

    {

    *(.bss)

    }

    bss_end = .;

}

运行的结果:

11.汇编代码简单操作第3张

接下来是汇编代码的操作实现:

mov r1,#6

mov r2,r1

mov r3,#10

11.汇编代码简单操作第4张

@mvn:传值取反的值

    mvn r0,#4 @r0:4取反变为-5

    mvn r1,#0b111000

    mvn r2,r1 @r2:0b111000

11.汇编代码简单操作第5张

Sub的实例:

11.汇编代码简单操作第6张

Add的实例:

11.汇编代码简单操作第7张

当然,我们也可以在执行的时候指定参数的值:如下图,我们指定了r0=44,r2=66.

11.汇编代码简单操作第8张

运行了之后:

11.汇编代码简单操作第9张

And的实例;

11.汇编代码简单操作第10张

11.汇编代码简单操作第11张

Bic的实例:第三个数是源码,源码位为1的,对应的位清0,源码位是0的,对应的位不变。

11.汇编代码简单操作第12张

从上面的执行结果看到,r1的最高位,和最低两位的1,对应源码位的值都是1,所以,被清0,中间四位,对应源码的四个0,保持不变1010.所以最后输出了0b101000.

  1. 比较指令

    Cmp指令的操作:比较的结果不会保持,回去影响cpsr对应的位:N或Z位。

    11.汇编代码简单操作第13张

    我们可以看到r1-1=1是正数,cpsr的最高位四位2=0010,N,Z位都是0.

    11.汇编代码简单操作第14张

    这里r1-3=-1,cpsr的最高四位8=1000,即是N位被置为1,表示结果是负数。

    11.汇编代码简单操作第15张

    这里r1-2=0,cpsr的次高位被置为1,表示两个数相等。

    Txt指令的操作:测试位、按位与,结果为0 ,Z位被置为1,结果不为0,Z位置为0

    11.汇编代码简单操作第16张

    按位与之后的值不为0,所以cpsr的Z位不会被置为1.

    11.汇编代码简单操作第17张

    按位与之后的结果是为0的,所以cpsr的Z位被置1.结果高四位的值是4.

  2. 跳转指令:

    B指令:

    11.汇编代码简单操作第18张

    上面的例子中,gt表示大于的时候跳转,6>5所以跳转到标签branch1处执行。不会执行add r3,r1,r2.

    11.汇编代码简单操作第19张

    上面,跳转的条件不成立,顺序执行,不跳转。但是会顺序执行,所以加个b end跳转到end,执行空操作。

    Bl:带链接的跳转:

    11.汇编代码简单操作第20张

    Lr:11.汇编代码简单操作第21张

    反汇编的代码:

    11.汇编代码简单操作第22张

    由上面看到lr保存的是bl返回来后的下一条地址,把他赋值给pc指针进行跳转。

  3. 移位指令:
  4. Lsl左移指令:

    11.汇编代码简单操作第23张

    11左移两位:1100

  5. ror循环右移:

    11.汇编代码简单操作第24张

    循环右移,最低位的1,被循环移动到了最高位。

  6. 程序状态字访问指令。

    在GNU汇编中,我们不允许上面的 指令来操作访问我们的程序字状态寄存器指令,所以我们需要将他们的值移出,再进行操作访问,修改等,操作完还要移进去。所以就设计到两个指令:MSR和MRS指令。搬出mrs,搬回去msr。

    11.汇编代码简单操作第25张

    11.汇编代码简单操作第26张

    执行了之后:

    11.汇编代码简单操作第27张

    11.汇编代码简单操作第28张

    最后:

    11.汇编代码简单操作第29张

    11.汇编代码简单操作第30张

    我们就是得通过上面的操作来改变cpsr里的值的。

  7. 存储器访问指令:

    上面的都是核里面的指令,内存是通过存储器访问质指令。

    Ldr指令:内存保存到寄存器

    Str指令:寄存器保存到内存。

    11.汇编代码简单操作第31张

    我们把r1设置成了开发板内存的地址,如上图,接下来在memory里创建一个监控的地址:

    11.汇编代码简单操作第32张

    11.汇编代码简单操作第33张

    接下来看看运行了上面的指令后的变化:如下图,我们的0xff已经被保存到了0x50008000.

    11.汇编代码简单操作第34张

    下面是ldr:

    11.汇编代码简单操作第35张

    R2的值就是存进r0里的值,被取出来了。

    这个汇编操作的工程代码:

    .text

    .global _start

    _start:

        @ldr和str的操作

        mov r0,#0xff

        str r0,[r1]

        ldr r2,[r1]

        @程序状态字寄存器访问

        mrs r0,cpsr

        orr r0,#0b100

        msr cpsr,r0

        @ror:循环右移

        mov r1,#0b11

        mov r1,r1,ror#1

        @lsl:左移

        mov r1,#0b11

        mov r1,r1,lsl#2

        @bl指令:带链接跳转

        bl func1

        @b指令:

        mov r1,#6

        mov r2,#7

        cmp r1,r2

        bgt branch1@gt表示大于的时候跳转

        add r3,r1,r2

        b end

    func1:

        mov r1,#23

        mov pc,lr@函数的返回,固定格式。

    branch1:

        sub r3,r1,r2

    end:

        nop

        @tst指令:

        mov r1,#0b101

        tst r1,#0b01

        mov r1,#0b101

        tst r1,#0b10

        @cmp指令的操作:

        mov r1,#2

        cmp r1,#1

        mov r1,#2

        cmp r1,#3

        mov r1,#2

        cmp r1,#2

        @bic:位清除指令

        mov r1,#0b1101011

        bic r2,r1,#0b1000011

        @and的用法:逻辑与

        mov r1,#5

        and r2,r1,#0

        mov r1,#5

        and r2,r1,#1

        @add:加法:

        add r1,r0,r2

        @sub:减法,注意被减数不能是立即数

        mov r2,#4

        sub r0,r2,#2

        mov r1,#3

        sub r3,r1,r0

        @这是注释,mov指令

        mov r1,#6

        mov r2,r1

        mov r3,#10

        @mvn:传值取反的值

        mvn r0,#4 @r0:4取反变为-5

        mvn r1,#0b111000

        mvn r2,r1 @r2:0b111000

免责声明:文章转载自《11.汇编代码简单操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇tomcat服务器输入localhost可以访问,ip无法访问解决办法课上测试三下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

互联网产品怎么做数据埋点

在互联网产品上线之后,产品和运营人员需要即时了解产品的使用情况,有多少用户,用户使用了哪些功能,停留时长,使用路径。。。等。要回答这些问题,需要有数据,不能拍脑袋想当然。数据怎么得到呢?埋点就是采集数据的重要途径。 数据埋点不是新名词,在电脑网站出来之后就有统计工具,站长们很熟悉的谷歌、百度统计等工具,通过在HTML页面中嵌入它们提供的js代码实现数据采集...

关于“无法定位程序输入点getaddrinfo于动态链接库WS32_32.dll上”的问题

今天收到一个bug,说我们的产品在windows 2000的操作环境下无法正常安装运行,安装后弹出“无法定位程序输入点getaddrinfo于动态链接库WS32_32.dll上”的错误。 简单地在网上搜了一下,发现多个讨论和解决方案。 方案一:http://hi.baidu.com/tjmd/blog/ITem/e35d0dd787b540dda144df...

python学习笔记(九)内置函数

1 print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真 True 2 print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真 True 3 4 print(bin(10))#十进制转二进制 5 ejz=bin(100) #0b1010 6 print(ejz.replace('0...

【腾讯优测干货分享】如何降低App的待机内存(五)——优化dex相关内存及本章总结

本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/01Abwe0p1h3WLh28Tzg_Dw 1.5案例:优化dex相关内存 在上一节我们提到,随着代码功能的增加,代码复杂度也在不断地变大,这时候我们往往会发现Dalvik Other和dex mmap这两部分消耗的内存也在不...

EF Core 原理从源码出发(二)

紧接着我的上一篇博客,可以点击这里回到上一篇博客,上回分析到ef 两个重要的对象,StateManager和ChangeTracker这个对象,当我们向DbContext添加对象的时候我们会调用如下代码。 1 private EntityEntry<TEntity> SetEntityState<TEntity>(...

css3中的width:100vh以及calc(100vh + 10px)

转自:https://blog.csdn.net/qq_24581629/article/details/72377300 vh/vw    vh: 相对于视窗的高度, 视窗被均分为100单位的vh;   vw: 相对于视窗的宽度, 视窗被均分为100单位的vw;   vmax: 相对于视窗的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vma...