当前位置: 首页 > wzjs >正文

质量好网站建设商家app001推广平台

质量好网站建设商家,app001推广平台,无锡网站制作选哪家,墨玉县建设工程信息网内联汇编 需要使用特殊指令(ldrex/strex实现互斥访问)的时候需要使用内联汇编。下图是内联汇编的语法。 __asm__ 冒号之前的使用" "括起来的是汇编代码,下面这个例子只有一条汇编指令。下面这段代码的意思是把第1个操作数和第2个操作数累加起来放到第0…

内联汇编

需要使用特殊指令(ldrex/strex实现互斥访问)的时候需要使用内联汇编。下图是内联汇编的语法。

__asm__  冒号之前的使用" "括起来的是汇编代码,下面这个例子只有一条汇编指令。下面这段代码的意思是把第1个操作数和第2个操作数累加起来放到第0个操作数。最后一行代表除了上面那些寄存器之外还影响着什么寄存器。cc代表flags register。“r”(a)表示将a的值放入r这个寄存器中。“=r”(sum)表示这个寄存器的值会被放在sum这个变量中。

还有一种写法:“=&r”(a) earlyclobber:表示这个输出寄存器 在所有输入操作数还没加载完成之前就会被修改,在分配寄存器时,a用的寄存器从一开始就不能与任何输入寄存器重复防止GCC 把这个输出寄存器和某个输入变量放在同一个寄存器中。这是在涉及读-改-写(如 ldrex/strex)时非常关键的一个约束

#include <stdio.h>
#include <stdlib.h>int add(int a, int b)
{int sum;__asm__ volatile ("add %0, %1, %2\n""add %1, %1, #1\n""add %2, %2, #1\n":"=&r"(sum):"r"(a), "r"(b):"cc");return sum;
}int main(int argc, char **argv)
{int a;int b;if (argc != 3){printf("Usage: %s <val1> <val2>\n", argv[0]);return -1;}a = (int)strtol(argv[1], NULL, 0);	b = (int)strtol(argv[2], NULL, 0);	printf("%d + %d = %d\n", a, b, add(a, b));return 0;
}

 当上述代码:"=&r"(sum) 写为:"=r"(sum)的时候的结果1+2 = 4 , 这是因为由于 sum 和 a 用了同一个寄存器(x1),第二句实际是对 sum 又加了一次,所以 1 + 2 → 3 → +1 = 4

从汇编语言也可以看出x0 = x0 + x1  第二步 x0 = x0 + 1 第三步x1 = x1 + 1 。这就说明了为什么实现的结果是1+2 = 4.(这种情况就是操作数0和1在同一个寄存器)

 

将 代码写为"=&r"(sum)再次运行

 

 同步互斥失败案例

第一种情况比较简单,用一个全局变量来控制访问,这种情况在修改全局变量前中断来到,另一个进程再调用驱动就会导致失败。

第二种情况如下图所示,用一个变量直接控制是否访问,但是--valid这个可以拆分成先读出数据,再修改,最后写入数据,如果刚读出还没有修改的时候被抢占,变量还未修改,另外一个线程进程也能访问。

第三种情况如下图所示代码,在单核CPU可以实现锁,但是在多核CPU无法实现,一个锁刚关住一个CPU的中断,还未改变值,另外一个CPU也可以使用该驱动。 

使用原子变量实现互斥

在ARMv6以下的版本,这些原子操作的函数都会进行关中断和恢复中断,确保没有别的程序能够访问,但是在ARMv6及以上版本,使用的是如下方法:

 当asm_op,op为add的时候分析下面代码:3568内核中的文件和6ull板子上的不同。

#define ATOMIC_OP(op, asm_op)						\
static inline void atomic_##op(int i, atomic_t *v)			\
{									\register int w0 asm ("w0") = i;					\register atomic_t *x1 asm ("x1") = v;				\\asm volatile(							\__LSE_PREAMBLE							\ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op),			\
"	" #asm_op "	%w[i], %[v]\n")					\: [i] "+r" (w0), [v] "+Q" (v->counter)				\: "r" (x1)							\: __LL_SC_CLOBBERS);						\
}

 借助GPT展开上面那段代码:

static inline void atomic_add(int i, atomic_t *v)
{register int w0 asm ("w0") = i;register atomic_t *x1 asm ("x1") = v;asm volatile (__LSE_PREAMBLE
#ifdef USE_LSE"ldadd %w[i], %w[i], [%[v]]\n"
#else"1: ldxr %w[i], [%[v]]\n""   add %w[i], %w[i], %w0\n""   stxr w3, %w[i], [%[v]]\n""   cbnz w3, 1b\n"
#endif: [i] "+r"(w0), [v] "+Q"(v->counter): "r"(x1): "memory", "cc");
}

代码解释如下: 

 这样来看,在ARMv6及以上版本(多CPU),函数其实是有可能会被打断的,但是其实现了原子操作的效果,(但是打断了没有关系,重新执行上述代码,如下图,重新执行之后发现valid = 0 , 走if之外的分支)。

常用函数: atomic_inc_and_test():先加1,再判断新值是否等于0,等于0的话返回1;

atomic_del_and_test():先减1,再判断新值是否等于0,等于0的话返回1。

http://www.dtcms.com/wzjs/252014.html

相关文章:

  • 网站建设免征增值税吗深圳seo优化公司
  • 做海外正品代购的十个网站百度引流平台
  • 辛集做网站今天国内新闻
  • 企业门户网站数据库设计怎么做线上销售
  • 网上购物网站开发苏州企业网站关键词优化
  • 广州冼村人很有钱吗seo程序
  • 电子商务网站建设课程的心得google秒收录方法
  • 兴县做网站公司长沙百度网站推广优化
  • 2018网站做外链企业建站公司热线电话
  • 网站开发税率是多少深圳关键词优化平台
  • 郑口住房和城乡建设局网站深圳推广公司
  • 怎样做卡盟网站seo黑帽有哪些技术
  • 企业网站包含内容网上广告怎么推广
  • wordpress 导航图片seo门户
  • 零食天堂 专做零食推荐的网站铜川网站seo
  • 盐城网站建设制作工作室百度关键词搜索排名代发
  • 怎么敲代码做网站广州网站优化运营
  • 做模板网站的公司网络营销的四种形式
  • 广州学建设网站使用 ahrefs 进行 seo 分析
  • 我是做网站怎么赚钱吗莆田百度快照优化
  • 免费做电子书的网站360网站关键词排名优化
  • 怎么做传奇网站百度下载免费官方安装
  • 哪些网站是用vue做的seo文章外包
  • 婴儿衣服做的网站好网络推广培训班
  • wordpress怎样做手机站重庆专业做网站公司
  • 网站的qq客服接口怎么做在百度如何发布作品
  • 如何做好网站内容优化聚名网
  • 中装建设官网成都网站seo排名优化
  • 不包括seo推广培训中心
  • 上传网站到百度下载百度app到桌面