[实验]-从汇编代码来看volatile关键字的作用
2021/6/22 14:27:06
本文主要是介绍[实验]-从汇编代码来看volatile关键字的作用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
★★★ 个人博客导读首页—点击此处 ★★★
环境aarch64的交叉编译器
我们将C语言翻译成汇编代码,来看volatile关键字的作用
我们先看一段C语言代码
void udelay(uint64_t usec) { uint64_t start, cnt, delta,freq; volatile uint64_t delta_us = 0; //------------------在这里定义了一个volatile变量 uint64_t reference_ratio = 16; if(timer_start == 0) { generic_timer_start(); start = read_cntpct_el0(); delta_us = 1000; //------------------ 给这个变量赋值100 while(delta_us) //------------------ 使用这个变量,这里是判断该变量是否等于0,然后走相应逻辑 { cnt = read_cntpct_el0(); if(cnt != start) break; delta_us--; if(delta_us == 0) { base_frequency = 0; } } INFO("base_frequency %ld\n",base_frequency); } ...... }
翻译成汇编后,从汇编代码来看,delta_us=1000,直接将1000写道栈尾中了.
while(delta_us)代码,需要读出delta_us,也是种栈尾种读出来的
00000000002034b4 <udelay>: 2034b4: a9bd7bfd stp x29, x30, [sp,#-48]! 2034b8: 910003fd mov x29, sp 2034bc: a90153f3 stp x19, x20, [sp,#16] 2034c0: aa0003f3 mov x19, x0 2034c4: b00000c0 adrp x0, 21c000 <xxx_middle_mem_pool+0xa40> 2034c8: f90017bf str xzr, [x29,#40] 2034cc: 900000d4 adrp x20, 21b000 <buf+0xdb8> 2034d0: b94f9c00 ldr w0, [x0,#3996] 2034d4: 340000a0 cbz w0, 2034e8 <udelay+0x34> 2034d8: f9412a80 ldr x0, [x20,#592] 2034dc: b50003a0 cbnz x0, 203550 <udelay+0x9c> 2034e0: d37cee73 lsl x19, x19, #4 2034e4: 14000014 b 203534 <udelay+0x80> 2034e8: 97ffffdd bl 20345c <generic_timer_start> 2034ec: d53be022 mrs x2, cntpct_el0 2034f0: d2807d00 mov x0, #0x3e8 //------------------------ 0x3e8-#1000给x0赋值1000,x0就表示delta_us变量 2034f4: f90017a0 str x0, [x29,#40] //------------------------ 将这个变量写到栈尾内存(其实可能是main-memory,也可能写入到了cache中) 2034f8: f9412a80 ldr x0, [x20,#592] 2034fc: f94017a1 ldr x1, [x29,#40] //------------------------ 将这个变量从栈尾内存读出来,放到X1中 203500: b4000161 cbz x1, 20352c <udelay+0x78> //------------------------ 比较x1是否等于0,然后走相应的分支 203504: d53be021 mrs x1, cntpct_el0 203508: eb02003f cmp x1, x2 20350c: 54000101 b.ne 20352c <udelay+0x78> 203510: f94017a1 ldr x1, [x29,#40] //----------------------- 在操作(delta_us--)时,再次从内存中去读 203514: d1000421 sub x1, x1, #0x1 // 这样对应 delta_us-- 203518: f90017a1 str x1, [x29,#40] 20351c: f94017a1 ldr x1, [x29,#40] 203520: eb1f003f cmp x1, xzr 203524: 9a9f1000 csel x0, x0, xzr, ne
我们去除volatile关键字后,再翻译成汇编:
uint64_t delta_us = 0; //------------------在这里定义了一个volatile变量
翻译成汇编后,从汇编代码来看,delta_us=1000,只是将1000写入到了x0寄存器中
0000000002034b4 <udelay>: 2034b4: a9be7bfd stp x29, x30, [sp,#-32]! 2034b8: 910003fd mov x29, sp 2034bc: f9000bf3 str x19, [sp,#16] 2034c0: aa0003f3 mov x19, x0 2034c4: b00000c0 adrp x0, 21c000 <xxx_middle_mem_pool+0xa40> 2034c8: b94f9c00 ldr w0, [x0,#3996] 2034cc: 35000160 cbnz w0, 2034f8 <udelay+0x44> 2034d0: 97ffffe3 bl 20345c <generic_timer_start> 2034d4: d53be021 mrs x1, cntpct_el0 2034d8: d2807d00 mov x0, #0x3e8 //------------------------ 0x3e8-#1000给x0赋值100,x0就表示delta_us变量 2034dc: d53be022 mrs x2, cntpct_el0 2034e0: eb01005f cmp x2, x1 2034e4: 540000a1 b.ne 2034f8 <udelay+0x44> 2034e8: f1000400 subs x0, x0, #0x1 //------------------ 这行对应的delta_us-- 2034ec: 54ffff81 b.ne 2034dc <udelay+0x28> 2034f0: 900000c0 adrp x0, 21b000 <buf+0xdb8> 2034f4: f901281f str xzr, [x0,#592] 2034f8: 900000c0 adrp x0, 21b000 <buf+0xdb8> 2034fc: f9412801 ldr x1, [x0,#592]
总结volatile关键字的作用:其实就算告诉编译器,我要读写的数据,不要从X0-X30通用寄存器中读取,每次都要从内存中去读取,这里说的内存可能是主内存(main-memory)、也可能是各级cache等
这篇关于[实验]-从汇编代码来看volatile关键字的作用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南