linux 汇编 `.eabi_attribute',有趣的++i和i++

作为一个天天和代码“约会”的人来说i++和++i这玩意再熟悉不过了,因为使用频率太高了。

虽然如此,但也未必见得我们真的了解她,不妨猜猜下面的输出结果。

#inlcude

int main(void)

{

int i = , j = ;

printf("i[1] = %d i[2] = %d\n", i++ + ++i, ++i + i++);

printf("j[1] = %d j[2] = %d\n", j++ + j++, ++j + ++j);

return ;

}

最后结果是:

i[1] = 6 i[2] = 2

j[1] = 4 j[2] = 4

想要得出正确答案,仅仅知道前+和后+的区别是不够的,这里面有两个坑。

第一个是cpu处理前+和后+真正的执行过程。

第二个是printf这个“小妾”暗藏一腿。

先把简单的第二个坑填了,以一般的思维和习惯会下意识的认为printf先计算前面那个表达式(即代码中的i[1] 和 j[1]),然后计算后面那个表达式的值(即  代码中的i[2]和j[2]),事实却正好相反,要先算后面再算前面。

要想填平第一个大坑,我们需要研究编译后的汇编代码。

@by tid_think

@arm-linux-gcc -S test.c -o test.s

@tiny4412

.cpu arm1176jzf-s

.eabi_attribute ,

.fpu vfp

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.eabi_attribute ,

.file "test.c"

.section .rodata

.align

.LC0:

.ascii "i[1] = %d i[2] = %d\012\000"

.align

.LC1:

.ascii "j[1] = %d j[2] = %d\012\000"

.text

.align

.global main

.type main, %function

main:

@ args = , pretend = , frame =

@ frame_needed = , uses_anonymous_args =

@by tid_think

@关键代码

stmfd sp!, {fp, lr} @将fp,lr两个寄存器的值压栈

add fp, sp, # @fp = sp +

sub sp, sp, # @sp = sp +

mov r3, # @r3 =

str r3, [fp, #-] @将r3的值()写入 fp - 的地方 int i = 0

mov r3, # @r3 =

str r3, [fp, #-] @将r3的值()写入 fp - 的地方 int j = 0

ldr r1, .L2 @将.L2的地址加载到r1

ldr r3, [fp, #-] @将fp -8地址上的值(i = ) 给r3

add r3, r3, # @r3 = r3 + ===>i =

str r3, [fp, #-] @将r3的值()写入 fp - 的地方 i

ldr r2, [fp, #-] @将fp -8地址上的值(i = ) 给r2

ldr r3, [fp, #-] @将fp -8地址上的值(i = ) 给r3

add r2, r2, r3 @r2 = r2 + r =

ldr r3, [fp, #-] @将fp -8地址上的值(i = ) 给r3

add r3, r3, # @ r3 = r3 + =

str r3, [fp, #-] @将r3的值()写入 fp - 的地方 i

ldr r3, [fp, #-] @将fp -8地址上的值(i = ) 给r3

add r3, r3, # @ r3 = r3 + =

str r3, [fp, #-] @将r3的值()写入 fp - 的地方 i

ldr r0, [fp, #-] @将fp -8地址上的值(i = ) 给r0

ldr r3, [fp, #-] @将fp -8地址上的值(i = ) 给r3

add r3, r0, r3 @ r3 = r0 + r3 =

ldr r0, [fp, #-] @将fp -8地址上的值(i = ) 给r0

add r0, r0, # @r0 = r0 + =

str r0, [fp, #-] @将r0的值()写入 fp - 的地方

mov r0, r1 @r0 = r1 给printf传参数1

mov r1, r2 @r1 = r2 = 给printf传参数2

mov r2, r3 @r2 = r3 = 给printf传参数3

bl printf @调用printf打印

ldr r1, .L2+4 @开始计算j了............

ldr r2, [fp, #-]

ldr r3, [fp, #-]

add r2, r2, r3

ldr r3, [fp, #-]

add r3, r3, #

str r3, [fp, #-]

ldr r3, [fp, #-]

add r3, r3, #

str r3, [fp, #-]

ldr r3, [fp, #-]

add r3, r3, #

str r3, [fp, #-]

ldr r3, [fp, #-]

add r3, r3, #

str r3, [fp, #-]

ldr r0, [fp, #-]

ldr r3, [fp, #-]

add r3, r0, r3

mov r0, r1

mov r1, r2

mov r2, r3

bl printf

mov r3, #

mov r0, r3

sub sp, fp, #

ldmfd sp!, {fp, pc}

.L3:

.align

.L2:

.word .LC0

.word .LC1

.size main, .-main

.ident "GCC: (ctng-1.8.1-FA) 4.5.1"

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

汇编代码解析:

首先刨去没用的信息,直接从 31行开始看

33~35行都是对栈指针的一些偏移和保存。

从以上汇编代码看可以看出简单的两句C编译成汇编就是一大坨,如果用纯汇编写15行左右应该就能搞定 执行效率几乎是C的20倍……………………

谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family

开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?

开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

几个有趣的WEB设备API(二)

浏览器和设备之间还有很多有趣的接口, 1.屏幕朝向接口 浏览器有两种方法来监听屏幕朝向,看是横屏还是竖屏. (1)使用css媒体查询的方法 /* 竖屏 */ @media screen and (or ...

谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

谈谈一些有趣的CSS题目(一)-- 左边竖条的实现方法

开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型

开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit

开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

谈谈一些有趣的CSS题目(五)-- 单行居中,两行居左,超过两行省略

开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

谈谈一些有趣的CSS题目(六)-- 全兼容的多列均匀布局问题

开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

谈谈一些有趣的CSS题目(七)-- 消失的边界线问题

开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

随机推荐

cursor

BeginWaitCursor(); // display the hourglass cursor // do some lengthy processing Sleep(3000); EndWai ...

mysql视图的创建

视图内容的变化跟它所依赖的表的变化是同步的也是一致的. create or replace view viewname as select a.id.,a.name,a.sex,b.aid,b.sco ...

hdu 4417 Super Mario/树套树

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...

java的CyclicBarrier

CyclicBarrier直译叫循环屏障,作用有点像赛跑时吹哨的角色,它有2个构造方法,一个是int的arg1,另一个多了一个Runable的arg2 arg1:可以看做此次参加赛跑的人数 arg2: ...

adb概览及协议參考

原文:https://github.com/android/platform_system_core/blob/master/adb/OVERVIEW.TXT) Implementation note ...

TCP重传问题解决思路

处理线上问题经常会碰到网络抖动的情况, 网络抖动有可能就是TCP重传导致,下面简单说下TCP重传的排查思路,不一定能完全解决问题 1. 找运维同事确定是否是网线问题, 如果是网线问题请更换网线 2. ...

Python基础(os模块)

os模块用于操作系统级别的操作: os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当 ...

C++程序设计方法3:类中的静态成员

在类型前面加static修饰的数据成员,是隶属于类的,成为类的静态数据成员,也称为“类的变量” 静态数据成员被该类的所有对象共享(即所有对象中的这个数据域实际上处于同一个内存位置) 静态数据要在实现文 ...

C++ code:数值计算之矩形法求解积分问题

积分的通常方法是将区域切割成一个个的小矩形,然后求这些小矩形的和.小矩形切割得越细,计算精度就越高,可以将切割小矩形的数量作为循环迭代变量,将前后两个不同精度下的小矩形和之差,作为逼近是否达到要求的比 ...

uva 11183 Teen Girl Squad

题意: 有一个女孩,需要打电话让所有的人知道一个消息,消息可以被每一个知道消息的人传递. 打电话的关系是单向的,每一次电话需要一定的花费. 求出打电话最少的花费或者判断不可能让所有人知道消息. 思路: ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
arm-none-eabi-gcc -o "SENSOR_CB.elf" @"objects.list" -mcpu=cortex-m3 -T"C:\Users\WangBingqian\Desktop\SC10L151Cube\trunk\NO_FOTA_VERSION\STM32L151CBTXA_FLASH.ld" --specs=nosys.specs -Wl,-Map="SENSOR_CB.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group Core/Src/rs485.o: In function `get_sample_data_max_min_value': rs485.c:(.text.get_sample_data_max_min_value+0x0): multiple definition of `get_sample_data_max_min_value' Core/Src/lora_wan.o:lora_wan.c:(.text.get_sample_data_max_min_value+0x0): first defined here Core/Src/rs485.o: In function `computeMvScale': rs485.c:(.text.computeMvScale+0x0): multiple definition of `computeMvScale' Core/Src/lora_wan.o:lora_wan.c:(.text.computeMvScale+0x0): first defined here Core/Src/rs485.o: In function `computeMvScale_f': rs485.c:(.text.computeMvScale_f+0x0): multiple definition of `computeMvScale_f' Core/Src/lora_wan.o:lora_wan.c:(.text.computeMvScale_f+0x0): first defined here Core/Src/rs485.o: In function `generate_frag_data': rs485.c:(.text.generate_frag_data+0x0): multiple definition of `generate_frag_data' Core/Src/lora_wan.o:lora_wan.c:(.text.generate_frag_data+0x0): first defined here Core/Src/rs485.o:(.bss.frag_num+0x0): multiple definition of `frag_num' Core/Src/lora_wan.o:(.bss.frag_num+0x0): first defined here collect2.exe: error: ld returned 1 exit status make: *** [makefile:50: SENSOR_CB.elf] Error 1 "make -j4 all" terminated with exit code 2. Build might be incomplete.是什么错误
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值