linux下c语言嵌入汇编

__asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法 <br /><br />__asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法 AT&T ASM Syntax<br />1 Overview <br /><br /><br /><br />开发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可以了,但至少和硬件相关部分的代码需要使用汇编语言,另外,由于启动部分的代码有大小限制,使用精练的汇编可以缩小目标代码的Size。另外,对于某些需要被经常调用的代码,使用汇编来写可以提高性能。所以我们必须了解汇编语言,即使你有可能 阅读详情

Using Assembly Language in Linux.

Intel和AT&T汇编语法差异:

1。前缀:

Intel汇编寄存器和立即数无需前缀。后者寄存器前缀为%,立即数前缀为$。

eg:

   Intex Syntax

   mov eax,1

   mov ebx,0ffh

   int 80h

 

   AT&T Syntax

   movl $1,%eax

   movl $0xff,%ebx

   int   $0x80

2。二者对操作数处理方向不同:

eg:

   Intel 汇编语法:

   instr dest,source

   mov eax,[ecx]

 

   AT&T 汇编语法:

   instr   source,dest

   movl (%ecx),%eax

3。内存变量语法差异:

Intel语法使用中括号[],后者使用小括号()

eg:

   Intex Syntax

   mov eax,[ebx]

   mov eax,[ebx+3]

 

   AT&T Syntax

   movl (%ebx),%eax

   movl 3(%ebx),%eax

4。后缀:

AT&T汇编指令有后缀,以表明数据类型(8位、16位等);Intel则根据寄存器自动识别。

eg:

   Intel Syntax

   mov al,bl

   mov ax,bx

   mov eax,ebx

   mov eax, dword ptr [ebx]

 

   AT&T Syntax

   movb %bl,%al

   movw %bx,%ax

   movl %ebx,%eax

   movl (%ebx),%eax

5。

Intel:segreg:[base+index*scale+disp]

AT&T: %segreg:disp(base,index,scale).

例子:

       1 #include <stdio.h>

       2

       3 int main(void) {

       4      long eax=4;

       5      long ebx=2;

       6

       7      __asm__ __volatile__ ("addl %1, %0"

       8              : "=b"((long)ebx)

       9              : "a"((long)eax), "b"((long)ebx)

      10              : "1"

      11              );

      12

      13      printf("ebx=%d/n", ebx);

      14      return 0;

      15 }

输出结果:ebx=6

linux下c语言内嵌汇编格式:

__asm__("<asm routine>" : output : input : modify);

output, input, modify都是引号括起来的字符串,他们直接用冒号分隔。

每个都可以有多项,项之间用逗号分隔,最多总共不能超过10个。

output要用“=”开头

寄存器缩写约定

Abbrev Register

a   %eax/%ax/%al

b   %ebx/%bx/%bl

c   %ecx/%cx/%cl

d   %edx/%dx/%dl

S   %esi/%si

D   %edi/%di

m   memory

q 由编译器在a、b、c、d中任意选择

寄存器还可以使用数字形式的缩写,0~9 (%0-%9),所以会有最多10个项的限制。

系统调用:

1。系统调用号存在eax中

2。系统调用参数要少于6个,分别存放在ebx, ecx, edx, esi, edi

3。返回值存在eax中

4。参数超过5个,用ebx指向存放参数的内存。如果压入堆栈,要注意参数顺序反过来。

汇编文件入口:

如果使用gcc编译,入口为main;如果用as和ld编译连接,入口使用_start,可以用ld的-e选项指定程序入口:ld -e main -o hello hello.o。

汇编程序运行时出现segmentation fault:

程序运行完时,处理器试图去执行下一个内存单元的指令,内存中没有指令或者为非法指令,硬件或者os包含机制就会发现

这个异常而产生段包含错误。解决方法,加上退出程序的系统调用就可以了。

eg:

       1 #.include "defines.h"

       2 .data

       3 hello:

       4 .string "hello world/n"

       5

       6 .globl   main

       7 main:

       8 #write

       9 movl     $4,%eax

      10 #stdout

      11 movl     $1,%ebx

      12 #content

      13 movl     $hello,%ecx

      14 #length of string

      15 movl     $12,%edx

      16 #system call

      17 int      $0x80

      18

      19 #exit

      20 movl     $1,%eax

      21 int      $0x80

      22

      23 ret

//------------------------------------------------------------------------------------------------------------------------

//  详细说明:

//------------------------------------------------------------------------------------------------------------------------

1.内嵌汇编举例

在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作。使用内嵌汇编,要先编写汇编指令模板,然后将C语言表达式与指令的操作数相关联,并告诉GCC对这些操作有哪些限制条件。例如在下面的汇编语句:

__asm__ __violate__(

"movl %1,%0"

: "=r" (result)

: "m" (input)

);

其中“movl %1,%0”是指令模板;“%0”和“%1”代表指令的操作数,称为占位符,内嵌汇编靠它们将C语言表达式与指令操作数相对应。指令模板后面用小括号括起来的是C语言表达式也即我们通常所说的变量,本例中只有两个:“result”和“input”,他们按照出现的顺序分别与指令操作数“%0”,“%1,”对应;注意对应顺序:第一个C表达式对应“%0”;第二个表达式对应“%1”,依次类推,操作数至多有10个,分别用“%0”,“%1”….“%9,”表示。在每个操作数前面有一个用引号括起来的字符串,字符串的内容是对该操作数的限制或者说要求。“result”前面的限制字符串是“=r”,其中“=”表示“result”是输出操作数,“r”表示需要将“result”与某个通用寄存器相关联,先将操作数的值读入寄存器,然后在指令中使用相应寄存器,而不是“result”本身,当然指令执行完后需要将寄存器中的值存入变量“result”,从表面上看好像是指令直接对“result”进行操作,实际上GCC做了隐式处理,这样我们可以少写一些指令。“input”前面的“r”表示该表达式需要先放入某个寄存器,然后在指令中使用该寄存器参加运算。

我们将上面的内嵌代码放到一个C源文件中,然后使用gcc –c–S得到该C文件源代码相对应的汇编代码,然后查看一下汇编代码,看看GCC是如何处理的。

C源文件如下内容如下,注意该代码没有实际意义,仅仅作为例子。

extern int

input,result;

void test(void)

{

input= 1;

__asm__ __volatile__ ("movl %1,%0" :

"=r" (result) : "r" (input));

return;

}

对应的汇编代码如下;

行号          代码                 解释

1

7

8               movl $1, input     对应C语言语句input = 1;

9               movl input, %eax                              

10 #APP GCC插入的注释,表示内嵌汇编开始

11             movl %eax,%eax       我们的内嵌汇编语句

12 #NO_APP GCC 插入的注释,表示内嵌汇编结束

13             movl %eax, result      将结果存入result变量

从汇编代码可以看出,第9行和第13行是GCC,自动增加的代码,GCC根据限定字符串决定如何处理C表达式,本例两个表达式都被指定为“r”型,所以先使用指令:

movl input, %eax

将input读入寄存器%eax;GCC,也指定一个寄存器与输出变量result相关,本例也是%eax,等得到操作结果后再使用指令:

movl %eax, result

将寄存器的值写回C变量result中。

从上面的汇编代码我们可以看出与result和input,相关连的寄存器都是%eax,GCC使用%eax,替换内嵌汇编指令模板中的%0,%1 。movl %eax,%eax显然这一句可以不要。但是没有优化,所以这一句没有被去掉。

由此可见,C表达式或者变量与寄存器的关系由GCC自动处理,我们只需使用限制字符串指导GCC如何处理即可。限制字符必须与指令对操作数的要求相匹配,否则产生的汇编代码将会有错,读者可以将上例中的两个“r”,都改为“m”(m,表示操作数放在内存,而不是寄存器中),编译后得到的结果是:movl input, result  很明显这是一条非法指令,因此限制字符串必须与指令对操作数的要求匹配。例如指令movl允许寄存器到寄存器,立即数到寄存器等,但是不允许内存到内存的操作,因此两个操作数不能同时使用“m”作为限定字符。

2 语法

内嵌汇编语法如下:

__asm__(

汇编语句模板:

输出部分:

输入部分:

破坏描述部分)

共四个部分:汇编语句模板,输出部分,输入部分,破坏描述部分,各部分使用“:”格开,汇编语句模板必不可少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空。例如:

__asm__ __volatile__(

"CLI":

:"memory")

2.1 汇编语句模板

汇编语句模板由汇编语句序列组成,语句之间使用“;”、“/n”或“/n/t”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1…,%9。指令中使用占位符表示的操作数,总被视为long型(4,个字节),但对其施加的操作根据指令可以是字或者字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在%和序号之间插入一个字母,“b”代表低字节,“h”代表高字节,例如:%h1。

2.2 输出部分

输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C语言变量组成。每个输出操作数的限定字符串必须包含“=”表示他是一个输出操作数。

例:

__asm__ __volatile__(

"pushfl ;

 popl %0 ;

 cli"

:"=g" (x)

 )

描述符字符串表示对该变量的限制条件,这样GCC就可以根据这些条件决定如何分配寄存器,如何产生必要的代码处理指令操作数与C表达式或C变量之间的联系。

2.3 输入部分

输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符由限定字符串和C语言表达式或者C语言变量组成。

例1:

__asm__ __volatile__ (

"lidt %0"

 :

 : "m" (real_mode_idt)

);

例二(bitops.h):

Static __inline__ void __set_bit(int nr, volatile void * addr)

{

__asm__(

"btsl%1,%0" :

"=m"(ADDR) :

"Ir"(nr));

}

后例功能是将(*addr)的第nr位设为1。第一个占位符%0与C语言变量ADDR对应,第二个占位符%1与C语言变量nr对应。因此上面的汇编语句代码与下面的伪代码等价:

btsl nr, ADDR,

该指令的两个操作数不能全是内存变量,因此将nr的限定字符串指定为“Ir”,将nr,与立即数或者寄存器相关联,这样两个操作数中只有ADDR为内存变量。

2.4 限制字符

2.4.1 限制字符列表

限制字符有很多种,有些是与特定体系结构相关,此处仅列出常用的限定字符和i386中可能用到的一些常用的限定符。它们的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系,例如是将变量放在寄存器中还是放在内存中等,下表列出了常用的限定字母。

分类 限定符 描述 通用寄存器

“a”将输入变量放入eax

这里有一个问题:假设eax已经被使用,那怎么办?

其实很简单:因为GCC知道eax已经被使用,它在这段汇编代码的起始处插入一条语句pushl %eax,将eax内容保存到堆栈,然后在这段代码结束处再增加一条语句popl %eax,恢复eax的内容

“b”将输入变量放入ebx

“c”将输入变量放入ecx

“d”将输入变量放入edx

“s”将输入变量放入esi

“d”将输入变量放入edi

“q”将输入变量放入eax,ebx ,ecx ,edx中的一个

“r”将输入变量放入通用寄存器,也就是eax ,ebx,ecx,edx,esi,edi中的一个

“A”把eax和edx,合成一个64位的寄存器(uselong longs)

“m”内存变量

“o”操作数为内存变量,但是其寻址方式是偏移量类型,也即是基址寻址,或者是基址加变址寻址

“V”操作数为内存变量,但寻址方式不是偏移量类型

“,” 操作数为内存变量,但寻址方式为自动增量

“p”操作数是一个合法的内存地址(指针)

寄存器或内存

“g” 将输入变量放入eax,ebx,ecx ,edx中的一个或者作为内存变量

“X”操作数可以是任何类型

立即数

“I” 0-31 之间的立即数(用于32位移位指令)

“J” 0-63 之间的立即数(用于64 位移位指令)

“N” 0-255 ,之间的立即数(用于out 指令)

“i” 立即数

“n” 立即数,有些系统不支持除字以外的立即数,这些系统应该使用“n”而不是“i”

匹配

“0”,“1 ,”... “9 ”

表示用它限制的操作数与某个指定的操作数匹配,也即该操作数就是指定的那个操作数,例如用“0 ”去描述“%1”操作数,那么“%1”引用的其实就是“%0”操作数,注意作为限定符字母的0-9 ,与指令中的“%0”-“%9”的区别,前者描述操作数,后者代表操作数。

后面有详细描述 & 该输出操作数不能使用过和输入操作数相同的寄存器后面有详细描述

操作数类型

“=” 操作数在指令中是只写的(输出操作数)

“+” 操作数在指令中是读写类型的(输入输出操作数)

浮点数

“f”浮点寄存器“t”第一个浮点寄存器“u”第二个浮点寄存器“G”标准的80387浮点常数% 该操作数可以和下一个操作数交换位置例如addl的两个操作数可以交换顺序(当然两个操作数都不能是立即数)# 部分注释,从该字符到其后的逗号之间所有字母被忽略* 表示如果选用寄存器,则其后的字母被忽略现在继续看上面的例子,"=m" (ADDR)表示ADDR为内存变量(“m”),而且是输出变量(“=”);"Ir" (nr)表示nr,为0-31之间的立即数(“I”)或者一个寄存器操作数(“r”)。

 

2.4.2 匹配限制符

I386

指令集中许多指令的操作数是读写型的(读写型操作数指先读取原来的值然后参加运算,最后将结果写回操作数),例如addl %1,%0,它的作用是将操作数%0与操作数%1的和存入操作数%0,因此操作数%0是读写型操作数。老版本的GCC对这种类型操作数的支持不是很好,它将操作数严格分为输入和输出两种,分别放在输入部分和输出部分,而没有一个单独部分描述读写型操作数,因此在GCC中读写型的操作数需要在输入和输出部分分别描述,靠匹配限制符将两者关联到一起注意仅在输入和输出部分使用相同的C变量,但是不用匹配限制符,产生的代码很可能不对,后面会分析原因。匹配限制符是一位数字:“0”、“1”……“9,”,分别表示它限制的C表达式分别与占位符%0,%1,……%9对应的C变量匹配.

例如使用“0”作为%1,的限制字符,那么%0和%1表示同一个C,变量。看一下下面的代码就知道为什么要将读写型操作数,分别在输入和输出部分加以描述。该例功能是求input+result的和,然后存入result:

extern int input,result;

void test_at_t()

{

result= 0;

input = 1;

__asm__

__volatile__ ("addl %1,%0":"=r"(result): "r"(input));

}

对应的汇编代码为:

movl $0,_result

movl $1,_input

movl _input,%edx /APP

addl %edx,%eax /NO_APP

movl %eax,%edx

movl %edx,_result

input 为输入型变量,而且需要放在寄存器中,GCC给它分配的寄存器是%edx,在执行addl之前%edx,的内容已经是input的值。可见对于使用“r”限制的输入型变量或者表达式,在使用之前GCC会插入必要的代码将他们的值读到寄存器;“m”型变量则不需要这一步。读入input后执行addl,显然%eax的值不对,需要先读入result的值才行。再往后看:movl %eax,%edx和movl %edx,_result的作用是将结果存回result,分配给result的寄存器与分配给input的一样,都是%edx。

 

综上可以总结出如下几点:

1. 使用“r”限制的输入变量,GCC先分配一个寄存器,然后将值读入寄存器,最后用该寄存器替换占位符;

2. 使用“r”限制的输出变量,GCC会分配一个寄存器,然后用该寄存器替换占位符,但是在使用该寄存器之前并不将变量值先读入寄存器,GCC认为所有输出变量以前的值都没有用处,不读入寄存器(可能是因为AT&T汇编源于CISC架构处理器的汇编语言,在CISC处理器中大部分指令的输入输出明显分开,而不像RISC那样一个操作数既做输入又做输出,例如add r0,r1,r2,r0,和r1是输入,r2是输出,输入和输出分开,没有使用输入输出型操作数,这样我们就可以认为r2对应的操作数原来的值没有用处,也就没有必要先将操作数的值读入r2,因为这是浪费处理器的CPU周期),最后GCC插入代码,将寄存器的值写回变量;

3. 输入变量使用的寄存器在最后一处使用它的指令之后,就可以挪做其他用处,因为已经不再使用。例如上例中的%edx。在执行完addl之后就作为与result对应的寄存器。

因为第二条,上面的内嵌汇编指令不能奏效,因此需要在执行addl之前把result的值读入寄存器,也许再将result放入输入部分就可以了(因为第一条会保证将result先读入寄存器)。修改后的指令如下(为了更容易说明问题将input限制符由“r,”改为“m”):

extern int input,result;

void test_at_t()

{

result = 0;

input = 1;

__asm__

__volatile__ ("addl %2,%0":"=r"(result):"r"(result),"m"(input));

}

看上去上面的代码可以正常工作,因为我们知道%0和%1都和result相关,应该使用同一个寄存器,但是GCC并不去判断%0和%1,是否和同一个C表达式或变量相关联(这样易于产生与内嵌汇编相应的汇编代码),因此%0和%1使用的寄存器可能不同。我们看一下汇编代码就知道了。

movl $0,_result

movl $1,_input

movl _result,%edx /APP

addl _input,%eax /NO_APP

movl %eax,%edx

movl %edx,_result

现在在执行addl之前将result的值被读入了寄存器%edx,但是addl指令的操作数%0却成了%eax,而不是%edx,与预料的不同,这是因为GCC给输出和输入部分的变量分配了不同的寄存器,GCC没有去判断两者是否都与result相关,后面会讲GCC如何翻译内嵌汇编,看完之后就不会惊奇啦。

使用匹配限制符后,GCC知道应将对应的操作数放在同一个位置(同一个寄存器或者同一个内存变量)。使用匹配限制字符的代码如下:

extern int input,result;

void test_at_t()

{

result = 0;

input = 1;

__asm__

__volatile__ ("addl %2,%0":"=r"(result):"0"(result),"m"(input));

}

输入部分中的result用匹配限制符“0”限制,表示%1与%0,代表同一个变量,输入部分说明该变量的输入功能,输出部分说明该变量的输出功能,两者结合表示result是读写型。因为%0和%1,表示同一个C变量,所以放在相同的位置,无论是寄存器还是内存。

相应的汇编代码为:

 

movl $0,_result

movl $1,_input

movl _result,%edx

movl %edx,%eax /APP

addl _input,%eax /NO_APP

movl %eax,%edx

movl %edx,_result

可以看到与result相关的寄存器是%edx,在执行指令addl之前先从%edx将result读入%eax,执行之后需要将结果从%eax读入%edx,最后存入result中。这里我们可以看出GCC处理内嵌汇编中输出操作数的一点点信息:addl并没有使用%edx,可见它不是简单的用result对应的寄存器%edx去替换%0,而是先分配一个寄存器,执行运算,最后才将运算结果存入对应的变量,因此GCC是先看该占位符对应的变量的限制符,发现是一个输出型寄存器变量,就为它分配一个寄存器,此时没有去管对应的C变量,最后GCC,知道还要将寄存器的值写回变量,与此同时,它发现该变量与%edx关联,因此先存入%edx,再存入变量。

至此读者应该明白了匹配限制符的意义和用法。在新版本的GCC中增加了一个限制字符“+”,它表示操作数是读写型的,GCC知道应将变量值先读入寄存器,然后计算,最后写回变量,而无需在输入部分再去描述该变量。

例;

extern int input,result;

void test_at_t()

{

result = 0;

input = 1;

__asm__

__volatile__ ("addl %1,%0":"+r"(result):"m"(input));

}

此处用“+”替换了“=”,而且去掉了输入部分关于result的描述,产生的汇编代码如下:

movl $0,_result

movl $1,_input

movl _result,%eax /APP

addl _input,%eax /NO_APP

movl %eax,_result

L2:

movl %ebp,%esp

处理的比使用匹配限制符的情况还要好,省去了好几条汇编代码。

2.4.3 “&”限制符

限制符“&”在内核中使用的比较多,它表示输入和输出操作数不能使用相同的寄存器,这样可以避免很多错误。

举一个例子,下面代码的作用是将函数foo的返回值存入变量ret中

__asm__ ( “call foo;movl %%edx,%1”, :”=a”(ret) : ”r”(bar) );

我们知道函数的int型返回值存放在%eax中,但是gcc编译的结果是输入和输出同时使用了寄存器%eax,如下:

movl bar, %eax

#APP

call foo

movl %ebx,%eax

#NO_APP

movl %eax, ret

结果显然不对,原因是GCC并不知道%eax中的值是我们所要的。避免这种情况的方法是使用“&”限定符,这样bar就不会再使用%eax寄存器,因为已被ret指定使用。

_asm__ ( “call foo;movl %%edx,%1”,:”=&a”(ret) : ”r”(bar) );

统计滤波器 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对统计滤波器做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。 阅读详情

相关推荐

ArcGIS遥感影像分类技术在植被覆盖度计算中的应用

本文详细介绍了如何利用ArcGIS遥感影像分类技术高效计算植被覆盖度。通过数据准备、监督与非监督分类方法详解,并结合制表分析与栅格计算器进行面积统计,最终实现从分类图到覆盖度百分比的全流程自动化与可视化,为生态评估与规划提供精准数据支持。

weixin_29091445的博客 421

在C语言中内嵌汇编语言

② 内嵌汇编指令中不要将R12~R14,R0~R3指定为指令中的物理寄存器,因为这些寄存器可能会存放中间结果或用于子程序调用;通常,内嵌汇编指令中不要指定物理寄存器。(3)R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能将R0~R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器;④ C语言程序中的标号可以被内嵌汇编指令使用,但指令BL不能使用C语言的标号(B指令则可以);(2)在使用物理寄存器时,不要使用过于复杂的C语言表达式,避免物理寄存器冲突;

CodeAllen嵌入式 1896

基于迁移学习的花卉识别系统

本研究采用了预训练的经典深度学习模型,包括ResNet、AlexNet和VGG,通过微调的方式在Oxford-102数据集和一个自制花卉数据集上进行训练,并对图像进行了多种数据增强操作,以提高模型的泛化能力,致力于实现花卉的高效分类。

m0_71146337的博客 2378

C语言内嵌汇编

最近阅读linux源码,发现很多以asm volatile开头的C语言内嵌汇编语代码的函数,于是了解了一下,c语言内嵌汇编代码格式为:__ asm __  __ volatile __”(“statements”: “output_regs”:“input_regs”:;clobbered_regs): “__ asm ”表示后面的代码为内嵌汇编,“asm”是“ asm ”的别名。 “...

qq_40712959的博客 2578

(一)ANSYS WORKBENCH实践入门

ANSYS-workbench 有限元分析应用基础教程 (张晔)学习笔记

qq_51767372的博客 1万+

台达伺服B3驱动器参数的设定和CN1的接法

3. B2的电子齿轮比是直接设定P1-44(分子)和P1-45(分母)就就可以的,但是B3的有个隐藏的细节,就是P1-44的默认值77216不用去更改,这是官方客服说的,需要改的是P1-45这个参数,比如说,我使用的丝杆螺距是5mm的,那么就是以5000脉冲走完5mm为一圈,则就把P1-45设定为5000即可;我的是三菱FX3S系列的PLC,是NPN型的,输出点是24V-作为信号的,所以接41、37,具体可参考B3的。,跟着客服的讲解操作才解决的,以下就是解决方法,希望能够帮到需要的各位。

qq_38681017的博客 1万+

STM32下C语言与汇编语言混合编程

目录 一、新建一个工程 1.新建工程 2.代码 二、C语言中调用汇编函数 1.无参数的调用 2.带有参数的调用 三、汇编语言中调用C语言函数 四、寄存器的使用规则 五、参考文献 一、新建一个工程 1.新建工程 打开下载好的MDK5,点击project,创建一个新的工程,命名文件并且保存,选择芯片,我选择的是STM32F103C8,然后点击CMSIS,勾选CORE选项,点击Device,勾选Starup选项,点击OK完成设置。 然后添加源main.c和f...

qq_57289359的博客 1167

Windows版本Carla(含RoadRunner插件)源码安装+RoadRunner地图导入

通过跳转浏览器账号密码登录github,不要选择Fine-grained personal access tokens,在git clone时会显示非授权,也不要使用Windows凭据!核心指令:编译PythonAPI–make PythonAPI,,编译Server–make launch,封装”游戏“–make package。完成安装后,在已安装->2022版本右侧->更多->导入配置,选择配置文件(需将配置文件内容更新为手册内容,如下图)->详细信息,更新。不要修改版本,执行上面指令即可!

winnizap的博客 1467

[转贴]linux下c语言嵌入汇编

 网上看到的这篇关于Linux下C语言嵌入汇编的文章写的非常全,转载过来。 Using Assembly Language in Linux.Intel和AT&T汇编语法差异:1。前缀:Intel汇编寄存器和立即数无需前缀。后者寄存器前缀为%,立即数前缀为$。eg:   Intex Syntax   mov eax,1   mov ebx,0ffh   in

ddna的专栏 1145

SAP PS项目计划成本与预算设计:从概念到可用性控制详解

在项目管理中,成本计划与预算管控是决定项目成本能否受控的两个核心概念。成本计划反映“预计花费”,预算是“授权上限”,两者在WBS结构上既相互关联又彼此独立。SAP PS通过计划版本管理不同口径的估算,并借助可用性控制机制对采购申请、采购订单等业务操作进行事前拦截与提示,从而实现从“事后追认”到“事前控制”的转变。理解计划成本作为预算基线、预算作为控制阀门的原理,能够帮助实施顾问和项目管理者合理设计项目财务流程。在大型工程、研发或总包项目中,明确WBS层级、预算对象和检查规则,可有效避免超支风险。围绕SAP

weixin_33146151的博客 360

python实现边缘检测Canny算子 (附完整源码)

python实现边缘检测Canny算子 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 457

Linux平台上C语言程序中嵌入汇编代码

#include <stdio.h> int main(void) { //AT&T asm systemcall: exit asm("nop\n\t"); //插入一条nop指令,不作任何操作 printf("Hello world\n"); return 0; } Linux平台上C语言中插入汇编语言实例。使用asm("***\n\t");汇编代码添加在双引号中,实例中的"***"添加汇编代码即可。如果是多行则每一行都加上“”双引号,且末尾.

qq_17012197的专栏 661

YOLOv5 自定义模型 Android 部署完整指南

本文详细介绍了将YOLOv5模型部署到Android设备的完整流程,包含三个核心部分:首先验证官方模型测试,确保基础环境配置正确;随后进行模型转换,从PyTorch导出ONNX格式并优化,再转换为NCNN格式;最后在Android项目中集成自定义模型,包括文件替换、参数修改和代码适配。教程基于YOLOv5 6.1版本,使用NCNN框架进行移动端推理,涵盖了常见问题解决方案和关键配置要点,为开发者提供了从训练到部署的完整技术路线。

FJN110的博客 592

视频教程-C语言嵌入式Linux编程第2期:计算机体系架构与ARM汇编语言-嵌入式

C语言嵌入式Linux编程第2期:计算机体系架构与ARM汇编语言 6年嵌入式...

weixin_30165499的博客 189

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Linux下C语言嵌入AT&T汇编

main.c #include <stdio.h> int a; int main() { asm( "pusha #this is a note\n" "movl $1,a\n" //a is a memory address "movl a,%eax\n" "add $2,%eax\n" "movl %eax,a\n" "popa" ); printf...

csdn_gddf102384398的博客 365

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

linux c嵌入汇编,嵌入式Linux——汇编语言,C语言基础(1)

首先,汇编语言的基础(间歇记录您的笔记... 2018-10-11)1. mov指令基本用法: mov r0,#0mov指令是分配指令. 用法如上. 将立即值0放入寄存器r0.2. bl命令bl是一个跳转指令,1)跳转到某个位置执行可以是汇编语言中的标签或c文件中的函数. 2)将返回地址保存到lr寄存器中,该返回地址为下一条指令的地址3.ldm和stm这两个与ldr和str不同. ldm和...

weixin_39664774的博客 267

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

linux c嵌入汇编语言,Linux 下的C和Intel 汇编语言混用

test.s (转载)--------------------------------------------------------------------; test.ssection.data; 数据段声明msg db "Hello, world!",0xA; 要输出的字符串len equ $ -msg; 字串长度section.text; 代码段声明global testtest:...

weixin_39624705的博客 159

C语言嵌入式Linux编程第2期:计算机体系架构与ARM汇编语言-王利涛-专题视频课程...

C语言到底学到什么程度,才能够胜任嵌入式Linux内核、驱动的开发? 不仅要求学员掌握C语言的基本语法,还要对 计算机基本原理、系统架构 、编译、链接原理、程序的加载、运行、C标准、 嵌入式硬件系统有深入理解。 本期是《C语言嵌入式Linux编程》第2期 学习过程中,有什么疑问,加入QQ群:475504428,与老师、其它学员一起交流...

宅学部落-王利涛 412

Linux内核入门(四)—— 内核汇编语言规则

    任何一个用高级语言编写的操作系统,其内核源代码中总有少部分代码是用汇编语言编写的。读过Unix Sys V源代码的读者都知道,在其约3万行的核心代码中用汇编语言编写的代码约2000行,分成不到20个扩展名为.s和.m的文件,其中大部分是关于中断与异常处理的底层程序,还有就是与初始化有关的程序以及一些核心代码中调用的公用子程序。     用汇编语言编写核心代码中的部分代码,

云(存储),松(耦合) 6727

嵌入式Linux ARM汇编(七)——C语言与ARM汇编混合编程

 转载:http://9291927.blog.51cto.com/9281927/1786072 在嵌入式系统开发中,目前使用的主要编程语言是C和汇编。在大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较好,便于人的理解,而且有大量的支持库。但是很多地方还是要用到汇编语言,例如开机时硬件系统的初始化,包括CPU状态的设定,中断的使能,主频的设定

qr_ljj的博客 1118
上一篇: x86寄存器说明
下一篇: 我的Linux PC开发环境
hgd_dingjun
博客等级 码龄21年 19粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值