学java的linux基础

学java的linux基础操作系统 API Application Programming Interface API 中文名为应用程序编程接口 是操作系统提供的一组 C 语言源代码文件 存放在 usr include 目录中 API 提供了程序频繁使用的功能 其中很多底层功能是使用系统调用实现的 在计算机操作系统发展早期 各种操作系统的 API 使用方式都不同 频繁学习不同的 API 非常耗费精力

大家好,我是讯享网,很高兴认识大家。



【操作系统API】

在计算机操作系统发展早期,各种操作系统的API使用方式都不同,频繁学习不同的API非常耗费精力,为此人们制定了统一的API规则,称为POSIX(可移植操作系统接口),它规定了API需要提供哪些功能、每种功能对应的函数和全局变量使用方式,开源操作系统的API基本上都遵循此规则。

API与C标准库深度融合,很多功能是由两者共同提供的,不分彼此,C标准库中的stdlib.h文件提供了很多看似应该由API提供的功能。

 ● mask

使用二进制位记录某种功能是否生效的数据称为mask,中文翻译为掩码,一般值为1表示生效、值为0表示不生效,有些功能使用一个二进制位记录生效状态,有些功能使用多个二进制位的组合记录生效状态,多个同类型mask指定的生效功能可以使用按位或运算进行整合。

 ● API函数执行结果

若执行出错后需判断出错具体原因,可以使用errno.h文件中的全局变量errno,其存储了API函数执行结果的具体原因,每一种执行结果使用一个数值表示,每个数值表示的含义不方便直接观察,可以使用stdio.h文件中的perror函数,perror会自动读取errno的值并输出其表示的含义。

注意:errno会随下次执行API函数而被修改,所以判断出错原因之前不能执行其它API函数。

 
 讯享网 

【GCC编译器】

将源代码制作为一个ELF文件需要经过三个步骤:编译、汇编、连接,三个步骤分别使用以下三种工具完成:

1.编译器,将高级语言代码转换为对应的汇编语言代码。

2.汇编器,将汇编语言代码转换为对应的指令数据、数学数据,GNU项目的汇编器为gas。

3.连接器,将编译后的文件添加必要的节组成ELF文件,GNU项目的连接器为ld。

gcc是编译器,只有编译功能,没有汇编与连接功能,但是因为编译、汇编、连接通常需要一起使用,所以在使用gcc编译代码时默认自动调用汇编器、连接器制作为ELF文件。

讯享网

 ● 预处理

1.将 #include 连接的文件内容复制到本文件中。

2.将使用 #define 定义的宏代码转换为具体的代码。

 ● GCC操作文件的类型

gcc通过文件后缀名自动确定文件类型,常用后缀如下:

cc,c++语言代码文件

cpp,c++语言代码文件

s,汇编语言代码文件

o,可重定向文件

so,动态连接库文件

out,可执行文件

 ● 常用参数

-o,小写字母o,指定编译后的文件名称,示例:gcc ~/a.c -o ~/ali.out,~/a.c为源代码文件路径,~/ali.out为编译后的文件路径,若不指定编译后的可执行文件存储路径,则默认存储路径为编译器工作目录,默认名称为a.out。

-O,大写字符O,设置编译优化级别,有4种级别,使用编号0-3表示,0表示不优化,3表示最高优化,默认为0级优化,级别值紧邻参数之后,示例:gcc -O2 ~/a.c。

------------------

-E,只进行预处理,不编译代码。

-S,只进行预处理、编译,不进行汇编、连接。

-c,只进行预处理、编译、汇编,不进行连接,用于制作可重定向文件。

-fpic,与-c组合使用,用于制作动态连接库使用的可重定向文件。

------------------

-static,调用连接库时使用静态库版本,而非动态库,编译后的程序体积会大很多。

-share,调用连接库时尽量使用动态库版本,生成的文件体积更小。

------------------

-g,添加调试功能相关数据,方便调试器调试程序,若不添加此参数则使用调试器调试程序时某些功能不可用,同时注意调试程序时不应该使用-O参数开启优化。

-s,编译后的程序不保存全局成员名称。

------------------

-masm,指定汇编代码的语法类型,比如在高级语言中内嵌汇编代码、或使用-S参数只编译代码时,都可以使用此参数,默认使用AT&T语法,若使用英特尔语法则应该添加参数 -masm=intel。

-std,设置C语言、C++语言的版本,比如:c89、c99、c11、c17、c++98、c++03、c++11、c++14、c++17,具体的版本值使用=符号赋值,示例:-std=c99,-std=c++03。

------------------

-w,不生成任何警告信息。

-Wall,生成所有警告和错误信息(数组越界访问除外),若不指定此参数则只显示必要的警告信息,比如设置了返回值的函数没有为返回值赋值,此时不使用此参数不会有警告。

-fpermissive,将不符合语法规则的某些代码改为可以编译,但是会生成警告信息,比如C++代码使用变量指针存储一个常量数据的地址,默认禁止编译,添加此参数即可编译,注意并非针对所有错误代码,有些错误不可忽略。

-fsanitize=address,检查源代码中各种内存错误访问相关信息,原理是在代码中添加各种检查代码,若出错则会在终端输出错误信息,并自动终止程序,一般用于调试程序。

------------------

-Idir,指定用户头文件的额外搜索路径,也就是在 #include 指令中使用""指定文件并使用相对路径时额外搜索的路径,参数值紧邻参数之后,示例:gcc -Idir/home/ali ~/a.c。

-I,指定所有类型头文件的额外搜索路径,使用 <> 和 "" 符号指定文件并使用相对路径时都会生效。

-L,指定静态连接库的额外搜索路径。

------------------

-v,查看gcc属性,包括gcc版本号。

【gdb调试器】

1.设置程序断点,程序执行到此处时会暂停。

2.程序单步执行,程序每执行一条指令就暂停。

3.查询程序执行时某些变量的值。

4.程序执行时临时修改某些变量的值。

使用gdb时首先在终端执行gdb程序,参数设置为要调试程序的路径,启动gdb后输入控制指令执行不同的功能,常用控制指令如下:

------------------

set args,设置被调试程序的main函数参数,示例:set args ali xyy,这里传入了2个参数,分别是ali和xyy。

list,显示程序源代码,示例:list 1,从第一行开始显示源代码,默认每次显示10行,之后按enter键显示下10行,示例:list main,显示main函数的源代码。

------------------

break/b,添加一个断点,可以使用代码行数或函数名指定断点添加处,程序执行到断点处会暂停,示例:break 9,在第9行添加一个断点。

info break/b,查询所有断点。

delete/d,取消一个断点,通过断点编号指定要删除的断点,示例:delete 1,取消编号为1的断点,示例:delete 1-5,取消编号1到5的断点。

disable,禁用指定编号的断点,示例:disable 1。

enable,启用指定编号的断点,示例:enable 1。

------------------

run/r,执行程序开始调试。

continue/c,在断点处恢复执行。

next/n,程序暂停后,单步执行下一条指令,若遇到跳转函数指令则忽略,执行之后的指令。

step/s,程序暂停后,单步执行下一条指令,若遇到跳转函数指令则进入函数,若跳转的函数是动态库函数则会产生错误。

finish/fin,程序暂停后,执行到下一个断点处,若本函数没有断点则执行到本函数末尾,并返回到上一级函数暂停。

until,跳转到源代码指定行数执行。

------------------

display,设置一个跟踪变量,每次暂停后自动查询此变量的值并输出,示例:display a,自动跟踪变量a。

undisplay,取消一个跟踪变量,需要使用跟踪变量编号指定,而不是变量名,示例:undisplay 1,取消编号为1的跟踪变量。

print/p,手动查询指定变量的值,示例:print a,查询变量a的值。

info locals,查询所有局部变量的值。

info reg,查询所有寄存器的值。

set var,修改指定变量的值,示例:set var a=0。

------------------

backtrace/bt,查询本函数调用者的执行顺序,也就是向前查询都有哪些函数执行。

call,跳转到指定函数执行一次并返回,同时输出此函数的返回值,示例:call ali(),跳转到ali函数执行,若有参数则需要同时为参数赋值。

disass,反汇编指定函数,示例:disass ali,反汇编ali函数。

------------------

quit/q,退出gdb。

注:有些控制指令可以使用简写,比如上述中的break/b,表示break可以简写为b。

【反汇编相关命令】

 ● 反汇编ELF文件

-h,显示文件头中的节说明信息。

-x,显示文件头中的所有属性信息。

-d,反汇编指令数据节,转换为汇编代码,包括init、plt、text、fini这四个节。

-D,反汇编所有节,转换为汇编代码,对于不完整的ELF文件可以使用此参数,自行判断哪些数据是指令。

-s,反汇编所有节,转换为16进制数据,同时显示数据对应的ASCII字符编码(若没有对应的字符编码则显示.符号)。

-M,设置汇编代码使用的语法规则,可以设置为AT&T语法、intel语法,默认使用AT&T语法。

 

 ● 查看ELF文件属性

使用readelf命令查看ELF文件的文件头、各种节属性,常用参数:

-h,查看文件头信息。

-l,查看程序头信息。

-S,查看节头信息。

-s,查看所有数据名、函数名。

-r,查看rela节信息。

-d,查看dynamic节信息。

-a,查看ELF文件的所有信息。

使用strings命令查询ELF文件中存储的字符串,这些字符串可能包含了程序功能的重要信息,示例:strings ~/a.out

使用ldd命令查询ELF文件使用了哪些动态库,示例:ldd ~/a.out

 ● 查看ELF文件内容

xxd、od、hexdump命令都可以查看ELF文件数据,这里以hexdump为例介绍。

常用参数:

-c,以ASCII字符方式显示。

-b,以8进制数据、单字节一组的方式显示。

-o,以8进制数据、双字节一组的方式显示。

-d,以10进制数据、双字节一组的方式显示。

-x,以16进制数据、双字节一组的方式显示。

-C,以16进制数据、双字节一组的方式显示,同时显示数据对应的ASCII字符。

-n,读取指定的文件长度(单位字节)。

讯享网

 ● 修改ELF文件内容

修改ELF文件数据可以使用hexedit命令,它使用16进制数据的方式进行修改,若操作系统没有自带此程序,可使用如下命令下载安装:sudo apt install hexedit,若有兴趣也可以通过API中的读写文件函数自行实现类似程序,更方便的方式是使用拥有图形界面的IDA进行ELF文件的反汇编以及数据修改,IDA官网有学习使用的免费版本(不能商用),具体使用方式这里不详细介绍。

【make】

make常用参数如下:

-f,指定make脚本文件的路径,若不指定则在工作目录中查找makefile文件。

-n,输出需要执行的操作,但是不真正的执行这些操作,用于检查makefile文件。

-j,指定使用CPU的几个核心进行工作,示例:make -j 4,使用4个核心。

-k,出现错误后继续执行,而非停止。

makefile脚本文件代码的基础编写规则如下。

 ● 注释

使用#符号设置一行注释。

 

 ● 创建行为

 

第一行用于设置行为名称以及此行为需要使用的文件和其它行为,action1为行为名,:符号之后编写此行为需要使用的文件(可省略)以及调用的其它行为(不可省略),上述代码指定了3个源代码文件。

行为名之后的行编写此行为执行的命令,每行命令开头需要使用tab键输入一个制表符。

    ★ 使用 @ 符号

默认情况下make会在终端输出执行了哪些命令,在命令前添加@符号则不输出。

 

    ★ 使用 - 符号

默认情况下遇到无法执行的命令make会终止执行,剩余命令都不会执行,在命令前添加-符号则命令执行出错时忽略,继续执行之后的命令。

 

 ● 使用多个行为

执行多个命令时往往需要将命令分类,放在不同的行为中,make默认从第一个行为开始执行,并且只执行第一个行为,其他行为需要被调用才能执行,并且被调用的行为会首先执行,就像C语言中的其它函数必须直接或间接的被main函数调用才能执行一样。

 

make从action1行为开始执行,此行为又调用了action2行为,action2会首先执行,之后再执行action1,最后的clean行为不会执行,需要在终端执行make时手动调用此行为执行,示例:make clean

 ● 使用字符串变量

定义行为时可以使用字符串指定行为属性,比如行为名称、行为使用文件、行为执行的命令。

学java的linux基础
 

    ★ 字符串赋值运算符

=运算符,直接赋值,多次使用=赋值时以最后一次赋值为准。

:=运算符,引用另一个字符串现在的值进行赋值。

?=运算符,有条件赋值,若变量没有赋值则进行赋值,若变量已经赋值则不进行赋值。

+=运算符,增加字符串中的字符,新增字符与原有字符使用空格分隔,常用于为执行命令添加参数。

 

    ★ 嵌套调用字符串

 

 ● 条件语句

 

 ● 函数

    ★ 使用 wildcard 函数查询文件名

 
 

    ★ 使用 patsubst 函数修改字符串

 

参数2,指定修改后的值

参数3,提供需要修改的字符串

 

    ★ 使用 foreach 函数循环处理字符串

 

参数2,需要处理的字符串。

参数3,每次循环对字符串的操作。

 

上述代码中,foreach会遍历字符串s1,每次循环会以空格作为分割符取其中一段内容,并将其临时存储到s2中,之后为此段内容添加.o,循环处理完s1的所有分段后将处理后的分段组合为一个字符串并返回。

    ★ 使用 dir 函数读取目录

 

 ● 进入子目录执行 make

 

同时还可以向子目录内的makefile脚本文件传递一个字符串变量。

 
小讯
上一篇 2025-01-02 16:10
下一篇 2024-12-30 15:47

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/2574.html