arm汇编
GNU 汇编语法GNU汇编语法适用于所有架构,每条语句有三个可选部分。
1label:instruction @ comment
label 即标号,表示地址位置,有些指令前面可能会有标号,这样就可以通过这个标号得到指令的地址,标号也可以用来表示数据地址。注意 label 后面的“:”,任何以“:”结尾的标识符都会被识别为一个标号。instruction 即指令,也就是汇编指令或伪指令。@符号,表示后面的是注释。comment 就是注释内容。
注意!ARM 中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用小写,但是不能大小写混用。
用户可以使用.section 伪操作来定义一个段,汇编系统预定义了一些段名:.text 表示代码段。.data 初始化的数据段。.bss 未初始化的数据段。.rodata 只读数据段。
常见的伪操作有:.byte 定义单字节数据,比如.byte 0x12。.short 定义双字节数据,比如.short 0x1234。.long 定义一个 4 字节数据,比如.long 0x12345678。.equ 赋值语句,格式为:.equ 变量名,表 ...
线程
进程线程是参与系统调度的最小单位。它被包含在进程之中,是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流(或者说是执行路线、执行流),一个进程中可以创建多个线程,多个线程实现并发运行,每个线程执行不同的任务。
任何一个进程都包含一个主线程,只有主线程的进程称为单线程进程.
那自然就存在多线程进程,所谓多线程指的是除了主线程以外,还包含其它的线程,其它线程通常由主线程来创建(调用pthread_create 创建一个新的线程),那么创建的新线程就是主线程的子线程。
主线程的重要性体现在两方面:⚫ 其它新的线程(也就是子线程)是由主线程创建的;⚫ 主线程通常会在最后结束运行,执行各种清理工作,譬如回收各个子线程。
线程是程序最基本的运行单位,而进程不能运行,真正运行的是进程中的线程。同一进程中的多个线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack,我们称为线程栈),自己的寄存器环境(register context)、自己的线程本地存储(thread-local storage)。
多进程编 ...
C issue2
堆栈空间C源代码进过预处理、编译、汇编和链接4步生成一个可执行程序。程序在没有运行之前,也就是说程序没有被加载到内存前,可执行程序内部已经分好3段信息,分别是代码区(text)、数据区(data)和未初始化数据区(bss)三个部分。(部分人直接把data和bss合起来叫做全局区或静态区)。运行可执行程序,系统把程序加载到内存,除了根据可执行程序的信息分出代码区、初始化数据区和未初始化数据区之外,还额外增加了栈区和堆区。
linux下的内存分配:
结构体和结构体指针的内存申请12345678910111213141516171819202122232425262728293031323334#include<stdio.h>#include<stdlib.h>//包含malloc函数的头文件#include<string.h>typedef struct student//typedef可以将struct student结构体类型用std替代{ char name[20]; int number; char subjec ...
进程
进程argc 和 argv 传参是如何实现的呢?
当在终端执行程序时,命令行参数(command-line argument)由 shell 进程逐一进行解析,shell 进程会将这些参数传递给加载器,加载器加载应用程序时会将其传递给应用程序引导代码,当引导程序调用 main()函数时,在由它最终传递给 main()函数,如此一来,在我们的应用程序当中便可以获取到命令行参数了。
注册进程终止处理函数atexit()
12#include <stdlib.h>int atexit(void (*function)(void));
function:函数指针,指向注册的函数,此函数无需传入参数、无返回值。返回值:成功返回 0;失败返回非 0。
进程是操作系统对一个正在运行的程序的一种抽象。
进程是一个动态过程,而非静态文件,它是程序的一次运行过程,当应用程序被加载到内存中运行之后它就称为了一个进程,当程序运行结束后也就意味着进程终止,这就是进程的一个生命周期。*
在应用程序中,可通过系统调用 getpid()来获取本进程的进程号
1234#include <sys/ty ...
C错题
11234567#include <stdio.h>int main() { int i = 1; sizeof(i++); printf("%d\n", i); return 0;}
输出等于1
根据C99规范, sizeof是一个编译时刻就起效果的运算符,在其内的任何运算都没有意义,sizeof(i++); 在编译的时候被翻译成 sizeof((i++的数据类型)) 也就是 sizeof(int); 不会执行i++了 。
sizeof是操作符
2下面说法中正确的是()
若全局变量仅在单个C 文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度
123- ``` 若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度
```设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑变量生命周期问题
123- ``` 静态全局变量使用过多,可那会导致动态存储区(堆栈)溢出
Static 函数在非类中有三个作 ...
信号
信号是事件发生时对进程的通知机制,也可以把它称为软件中断。信号与硬件中断的相似之处在于能够打断程序当前执行的正常流程,其实是在软件层次上对中断机制的一种模拟。大多数情况下,是无法预测信号达到的准确时间,所以,信号提供了一种处理异步事件的方法。
产生信号的方式:
⚫ 硬件发生异常,即硬件检测到错误条件并通知内核,随即再由内核发送相应的信号给相关进程。硬件检测到异常的例子包括执行一条异常的机器语言指令,诸如,除数为 0、数组访问越界导致引用了无法访问的内存区域等,这些异常情况都会被硬件检测到,并通知内核、然后内核为该异常情况发生时正在运行的进程发送适当的信号以通知进程。⚫ 用于在终端下输入了能够产生信号的特殊字符。譬如在终端上按下 CTRL + C 组合按键可以产生中断信号(SIGINT),通过这个方法可以终止在前台运行的进程;按下 CTRL + Z 组合按键可以产生暂停信(SIGCONT),通过这个方法可以暂停当前前台运行的进程。⚫ 进程调用 kill()系统调用可将任意信号发送给另一个进程或进程组。当然对此是有所限制的,接收信号的进程和发送信号的进程的所有者必须相同,亦或者发送信号的进 ...
Linux系统信息与系统资源
系统信息与系统资源系统信息系统标识uname系统调用uname()用于获取有关当前操作系统内核的名称和信息,原型可以通过man 2 uname查看
函数参数和返回值含义如下:buf:struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象。返回值:成功返回 0;失败将返回-1,并设置 errno。
uname()函数用法非常简单,先定义一个 struct utsname 结构体变量,调用 uname()函数时传入变量的地址即可,struct utsname 结构体如下所示:
12345678910struct utsname { char sysname[]; /* 当前操作系统的名称 */ char nodename[]; /* 网络上的名称(主机名) */ char release[]; /* 操作系统内核版本 */ char version[]; /* 操作系统发行版本 */ char machine[]; /* 硬件架构类型 */ #ifdef _GNU_SOURCE char domainname[];/* 当前域名 */ ...
Linux调试工具gdb
linux中使用C/C++的调试工具gdbgdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。
一般来说,GDB主要帮助你完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。首先要用gcc进行编译
1gcc -g 源文件 -o 目标文件
gdb的命令
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h
(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r
(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l
(gdb)set:设置变量的值
(gdb)next:单步调试(逐过程,函数直接执行),简写n
(gdb)ste ...
学习一个阶段的感受
因为疫情原因提前放假回家,大部分考试还不知道怎么考,现在要准备好材料,刷网课和弄选修论文,打算12月份学完C语言剩余两章,之后每天写个联系代码,linux方面继续应用层的编写学习,看看弄完后,可能要进入到C++,这样才能学习QT应用编程,东西还是不少的,先完成总的百分之40吧。
待续。。。
现在进入假期了,为了更好的使用linux的开发板,开始学习裸机开发,uboot和系统移植,驱动开发相关知识。
看看之后学习C++,进入qt来更好的制作一个完整的项目。
C issue1
scanf输入问题-输入缓冲区1234567891011121314151617181920212223int main(void){ char ch; int i=0; int b; b=scanf("%c",&ch); while(b == 1) { printf("%d",i++); printf("?"); b=scanf("%c",&ch);\ } printf("Done\n"); return 0;}//会得到```ca//输入a0?a1?
原因是因为scanf()函数会把回车、空格、Tab或一些不合理输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。
程序在输入a后输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充 ...