历史上的今天
返回首页

历史上的今天

今天是:2025年01月18日(星期六)

正在发生

2020年01月18日 | ARMv7汇编代码分析

2020-01-18 来源:eefocus

为了分析ARMv7架构寄存器的使用,利用C程序生成ARMv7汇编,并分析之。


1、C源程序代码如下(为了简化,函数功能很简单):

# cat  callfunc.c


#include

#include

#include

int main()

{

int input=10;

int tmp,result;

tmp = func1(input);

result = func2(tmp);

printf("result = %d n", result);

return 0;

}

 

int func1(int a)

{

a++;

return a;

}

 

int func2(int b)

{

b=b*b;

return b;

}


2、交叉编译生成ARM汇编代码:

# arm-none-linux-gnueabi-gcc -march=armv7-a  callfunc.c  -S -o callfunc.asm


生成ARMv7的汇编代码如下:


.arch armv7-a

.fpu softvfp

.eabi_attribute 20, 1

.eabi_attribute 21, 1

.eabi_attribute 23, 3

.eabi_attribute 24, 1

.eabi_attribute 25, 1

.eabi_attribute 26, 2

.eabi_attribute 30, 6

.eabi_attribute 34, 1

.eabi_attribute 18, 4

.file "callfunc.c"

.section .rodata

.align 2 ;2^2,即4字节对齐;以"."开头的是伪指令,具有编译器相关,平台无关性;

.LC0:

.ascii "result = %d 1200"

.text

.align 2

.global main ;全局函数声明,相当于C语言中的extern

.type main, %function

main:

.fnstart ;函数开始标志

@ args = 0, pretend = 0, frame = 16 ;@标志注释,由编译器添加

@ frame_needed = 1, uses_anonymous_args = 0


stmfd sp!, {fp, lr} ;fp=r11=0,lr=0x40291664

;分别存储fp,lr到sp,sp-4;sp0=sp-4;fp(R11)桢指针 ;

;关于fp:通常在C程序编译过程中,所有函数的局部变量被分配在一个连续的存储区中,

;一般这个存储区是在堆栈中,这个连续的存储区称为这个函数的存储“帧”,它是通过一个指针访问的。

;寄存器 fp (桢指针)应当是零或者是指向栈回溯结构的列表中的最后一个结构,

;提供了一种追溯程序的方式,来反向跟踪调用的函数。

;即:其作用是用来回溯,从代码中也可以看出来,fp只是起标签作用,理论上不使用fp也不会影响程序执行

.save {fp, lr} ;关于.save:其作用与以下.setfp、.pad等的伪指令作用类似,对相应汇编指令产生注释。

;具体注释内容见网页(http://sourceware.org/binutils/docs/as/ARM-Directives.html)

.setfp fp, sp, #4

add fp, sp, #4 ;sp=0xbe88f3e0,fp=0xbe88f3e4

.pad #16

sub sp, sp, #16 ;sp=0xbe88f3d0

mov r3, #10 ;r3=10

str r3, [fp, #-8] ;r3->fp-8即sp-4

ldr r0, [fp, #-8] ;r3->r0

bl func1 ;jump to func1

str r0, [fp, #-12] ;r0->fp-12

ldr r0, [fp, #-12]

bl func2

str r0, [fp, #-16]

movw r3, #:lower16:.LC0

movt r3, #:upper16:.LC0      ;movw和movt的作用为:r3 = (movt #:upper16:.LC0 << 16) | (movw #:lower16:.LC0)).

;以上两句的作用就是输出.LC0段的.ascii那一行的内容,即打印那个result = %d 1200

mov r0, r3

ldr r1, [fp, #-16]

bl printf ;打印r0、r1中内容

mov r3, #0

mov r0, r3

sub sp, fp, #4

ldmfd sp!, {fp, pc}

.fnend

.size main, .-main

.align 2

.global func1

.type func1, %function

func1:

.fnstart

@ args = 0, pretend = 0, frame = 8

@ frame_needed = 1, uses_anonymous_args = 0

@ link register save eliminated.

str fp, [sp, #-4]!      ;r11(fp)入栈;sp=0xbe88f3d0-4=0xbe88f3cc,r11=0xbe88f3e4;fp(即r11)存储到sp-4(0x)的地址中

.save {fp}

.setfp fp, sp, #0

add fp, sp, #0 ;fp=0xbe88f3cc

.pad #12

sub sp, sp, #12 ;sp=0xbe88f3c0

str r0, [fp, #-8] ;r0存储到fp-8指向的地址处

ldr r3, [fp, #-8]

add r3, r3, #1

str r3, [fp, #-8]

ldr r3, [fp, #-8]

mov r0, r3

add sp, fp, #0

ldmfd sp!, {fp} ;r11(fp)出栈

bx lr

.fnend

.size func1, .-func1

.align 2

.global func2

.type func2, %function

func2:

.fnstart

@ args = 0, pretend = 0, frame = 8

@ frame_needed = 1, uses_anonymous_args = 0

@ link register save eliminated.

str fp, [sp, #-4]!

.save {fp}

.setfp fp, sp, #0

add fp, sp, #0

.pad #12

sub sp, sp, #12

str r0, [fp, #-8]

ldr r3, [fp, #-8] ;r0->r3

ldr r2, [fp, #-8] ;r0->r2

mul r3, r2, r3 ;r2*r3->r3

str r3, [fp, #-8]

ldr r3, [fp, #-8]

mov r0, r3 ;r3->r0

add sp, fp, #0

ldmfd sp!, {fp};sp->fp ;pop fp

bx lr

.fnend

.size func2, .-func2

.ident "GCC: (Sourcery CodeBench Lite 2011.09-70) 4.6.1"

.section .note.GNU-stack,"",%progbits


分析内容见代码注释


注意:

1、编译器默认用来传输参数的寄存器是r0~r3,参数超过四个就要用到栈。

2、bl printf:该命令是打印命令,默认打印r0开始的寄存器内容,测试过参数超过4个时候,打印时r0存储打印格式,r1-r3存储要打印的数,剩下的参数需要其他寄存器存储,但是printf如何实现打印多出来的几个寄存器的,目前暂不清楚。欢迎补充。

推荐阅读

史海拾趣

德丰(DEFOND)公司的发展小趣事

德丰智能科技有限公司(简称“德丰智能”)是一家专注于智能科技产品研发和生产的企业。随着人工智能、物联网等技术的快速发展,德丰智能敏锐地捕捉到了这一市场机遇。公司加大了对智能科技产品的研发力度,成功推出了一系列具有自主知识产权的智能科技产品。这些产品不仅具有高度的智能化和自动化水平,还能够为用户带来更加便捷、高效的使用体验。通过不断的创新和市场拓展,德丰智能逐渐在智能科技领域崭露头角,成为了一家备受关注的新兴企业。

请注意,以上故事均为模拟内容,可能并不完全符合任何一家实际存在的“德丰(DEFOND)”公司的发展历程。如有需要,请查阅相关公司的官方资料以获取更准确的信息。

广州基安彼(GMB)公司的发展小趣事

台湾德丰股份有限公司(简称“台湾德丰”)自1961年成立以来,一直专注于房屋租售、商业大楼兴建等房地产相关业务。公司在长期的经营过程中,形成了稳健的发展风格和良好的市场口碑。台湾德丰凭借专业的服务团队和丰富的市场经验,成功在竞争激烈的房地产市场中占有一席之地。公司的发展不仅为员工创造了良好的工作环境和福利待遇,也为当地经济的发展做出了积极贡献。

EPC公司的发展小趣事

最后一家EPC公司深知创新是企业发展的核心动力。公司注重研发投入和人才培养,建立了专业的研发团队和完善的研发体系。公司不断跟踪行业发展趋势和技术动态,积极引进新技术、新工艺和新材料,推动产品升级和产业升级。同时,公司注重创新成果的转化和应用,将新技术、新工艺和新材料应用于实际项目中,提高了项目的竞争力和附加值。通过持续的创新和积累,公司逐渐在电子行业中形成了独特的技术优势和核心竞争力。

请注意,以上故事仅为框架性描述,并未包含具体的公司名称、项目细节和具体数字。您可以根据这些框架性描述进一步深入了解相关公司的发展情况,并结合实际案例进行具体分析和撰写。

Global Power Technologies Group公司的发展小趣事
选择合适的电阻、电容和三极管等元件,确保电路的稳定性和可靠性。
Coiltronics公司的发展小趣事

随着全球化趋势的加强,Coiltronics公司开始将目光投向国际市场。公司制定了一系列国际化战略,包括在海外市场设立分支机构、与当地企业合作等。通过这些举措,Coiltronics成功将其技术和产品推向国际市场,进一步扩大了公司的业务范围。同时,国际化战略也带来了公司管理、文化等方面的变革,为公司的长远发展注入了新的活力。

光磊(GL)公司的发展小趣事

随着全球化趋势的加强,Coiltronics公司开始将目光投向国际市场。公司制定了一系列国际化战略,包括在海外市场设立分支机构、与当地企业合作等。通过这些举措,Coiltronics成功将其技术和产品推向国际市场,进一步扩大了公司的业务范围。同时,国际化战略也带来了公司管理、文化等方面的变革,为公司的长远发展注入了新的活力。

问答坊 | AI 解惑

未来的神奇交通工具——智能汽车

  智能汽车最早有望在2020年停在你的车库里;到2030年,磁悬浮列车能够在2小时或更短的时间内帮你实现跨洲旅行。这是美国科学家的最新预言。     美国著名科普作家皮莱蒂尔表示,我们可以想象一下,将来乘坐智能汽车从拉斯维加 ...…

查看全部问答>

ARM开发人员换工作的收入方程式

工作是业余爱好,换工作损公司也损自已,对于个人的收入是 如果今天离职明天就职,那么当月收入是: 本月收入 = 旧公司日工资*天数 + 新公司日工资 * 天数 - 旧公司月工资 - 当月消费 例:某人旧公司工资9K,按上方程式填: 本月收入 = 6天 * 3 ...…

查看全部问答>

FX系列PLC编程手册

送个三菱手册手册大家看看。…

查看全部问答>

VC unsigned int转Cstring

说一下我的目的: 在2440+wince6.0的开发环境下,把10位ADC结果显示在液晶上。这样ADC采样结果是int型,而edit control需要字符串数据。 下面是我写的程序,输出的结果是0~255也就是转换后只有8位二进制数。我是要把AD转换结果显示到edit control ...…

查看全部问答>

打开SMS Editer的问题

(tmail.exe -service \"SMS\" -to \"\" -body\"\"). 以上两个的tmail.exe 和 -service \"SMS\" -to \"\" -body\"\"是否可以作为CreateProcess的前两个参数去打开SMS Editer? 第二个参数该怎么写呢?…

查看全部问答>

SetWindowLong函数老是失败

CPropertySheet* pSheet = new CPropertySheet(); ASSERT(pSheet); .. .. DWORD dwStyle = WS_CHILD | WS_VISIBLE; pSheet->Create(this,dwStyle); dwStyle = GetWindowLong(pSheet->GetSafeHwnd(),GWL_STYLE); int iError = GetLastError() ...…

查看全部问答>

A/D转换的值为什么随电源电压的变化而变化?

A/D转换的值为什么随电池电压的变化而变化?经过测量,参考电压输出不随电池电压变化,请问高手是怎么回事?…

查看全部问答>

Jlink V8可以支持LM4F吗?

不知道现在市面上流行的那些山寨Jlink V8是否支持新出的LM4F MCU?…

查看全部问答>