【汇编语言】流程转移和子程序

2024-04-25 16:52

本文主要是介绍【汇编语言】流程转移和子程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【汇编语言】流程转移和子程序


`

文章目录

  • 【汇编语言】流程转移和子程序
  • 前言
  • 一、“转移”综述
  • 二、操作符offset
  • 三、jmp指令
    • jmp指令——无条件转移
    • jmp指令:依据位移进行转移
    • 两种段内转移
    • 远转移:jmp far ptr 标号
    • 转移地址在寄存器中的jmp指令
    • 转移地址在内存中的jmp指令
    • jmp 指令小结
  • 四、其他转移指令
    • jcxz指令
    • loop指令
    • 根据位移进行“相对”转移的意义
  • 五、call 指令和 ret 指令
    • 模块化程序设计
    • call 指令
    • 指令“call far ptr 标号”实现的是段间转移
    • 转移地址在寄存器中的call指令
    • 转移地址在内存中的call指令
    • 返回指令:ret 和 retf
    • 执行过程
  • 六、call 和 ret 配合使用
    • 具有子程序的源程序的框架
    • call 和 ret 配合使用
    • 为call和ret指令设置栈
  • 七、乘法:mul 指令
    • 回顾:除法div指令
    • 用mul指令做乘法
    • 应用案例
  • 八、汇编语言模块化程序设计
    • 模块化程序设计
    • 参数和结果传递的问题
    • 用寄存器来储存参数和结果是最常使用的方法
    • 用内存单元批量传递数据
    • 用栈传递参数
    • 程序的执行过程中栈的变化
    • 小结:参数和结果传递的问题
  • 九、寄存器冲突问题
    • 引子
    • 编程将data段中的字符串转化为大写
    • 寄存器冲突问题的解决
    • 寄存器冲突问题的解决示例
  • 十、标志寄存器
    • 认识标志寄存器的特殊之处
    • ZF-零标志(Zero Flag)
    • PF-奇偶标志(Parity Flag)
    • SF-符号标志(Sign Flag)
    • CF-进位标志(Carry Flag)
    • OF-溢出标志(Overflow Flag)
    • 综合:一条指令会带来多个标志寄存器的变化
  • 十一、带进(借)位的加减法
    • adc带进位加法指令
    • adc指令应用:大数相加
    • 128 位数据相加
    • sbb 指令
  • 十二、cmp与条件转移指令
    • cmp指令
    • 无符号数比较与标志位取值
    • 有符号数比较与标志位取值
    • 条件转移指令
    • 条件转移指令的使用
  • 十三、条件转移指令的应用
    • 应用案例
  • 十四、DF标志和串传送指令
    • 问题分析
    • DF标志和串传送指令
    • rep指令
    • 应用实例
  • 总结


前言

在本篇文章当中我们将详细讲到,转移的综述,操作符offset,jmp指令,其他转移指令,call指令和ret指令,call指令和ret指令的配合使用,mul指令,汇编语言的模块化程序设计,寄存器冲突的问题和解决方法,标志寄存器,带进(借)位的加减法,cmp和条件转移指令,条件转移指令的应用,DF标志和串传送指令。


一、“转移”综述

背景:一般情况下指令是顺序地逐条执行的,而在实际中,常需要改变程序的执行流程。

转移指令:
可以控制CPU执行内存中某处代码的指令
可以修改IP,或同时修改CS和IP的指令
例:
在这里插入图片描述

转移指令分类:
在这里插入图片描述


二、操作符offset

用操作符offset取得标号的偏移地址****
格式:
offset 标号
例:
在这里插入图片描述
在这里插入图片描述

练习:
问题:有如下程序段,添写2条指令,使该程序在运行中将s处的一条指令复制到s0处
这边我已经给出了。
nop的机器码占一个字节,起“占位”作用在这里插入图片描述
我们来分析一下:
1)s和s0处的指令所在的内存单元的地址是多少?
cs:offset s 和cs:offset s0。
2)将s处的指令复制到s0处,就是________
就是将cs:offset s 处的数据复制到cs:offset s0处。
3)地址如何表示?
段地址已知在cs中,偏移地址已经送入si和di中。
4)要复制的数据有多长?
mov ax,bx指令的长度为两字节,即一个字


三、jmp指令

jmp指令——无条件转移

无条件转移,可以只修改IP,也可以同时修改CS和IP

jmp指令要给出两种信息:
转移的目的地址
转移的距离
段间转移(远转移): jmp 2000:1000
段内短转移: jmp short 标号 ; IP的修改范围为 -128~127,8位的位移
段内近转移: jmp near ptr 标号 ; IP的修改范围为 -32768~32767,16位的位移

jmp指令:依据位移进行转移

引子:常见指令中的立即数均在机器指令中有体现
在这里插入图片描述
可以看出立即数0123在机器码中有所体现。

问题:jmp short 指令中,转移到了哪里?
—>jmp short 的机器指令中,包含的是跳转到指令的相对位置,而不是转移的目标地址。
在这里插入图片描述
在这里插入图片描述
上边程序jmp short s指令的读取和执行:
1)(IP)=0003,CS:IP指向EB 05(jmp的机器码)
2) 读取指令码EB 05进入指令缓冲器;
3)(IP)=(IP)+所读取指令的长度=(IP)+2=0005,CS:IP指向add ax,0001;
4)CPU执行指令缓冲器中的指令EB05;
5)指令 EB 05执行后,(IP)=(IP)+05=000AH,CS:IP指向inc ax
在这里插入图片描述

两种段内转移

短转移:“jmp short 标号”
功能:(IP)=(IP)+8位位移
原理:
1)8位位移=“标号”处的地址-jmp指令后的第一个字节的地址;
2)short指明此处的位移为8位位移;
3)8位位移的范围为-128~127,用补码表示;
4)8位位移由编译程序在编译时算出。
在这里插入图片描述
在这里插入图片描述

近转移:指令“jmp near ptr 标号”
功能: (IP)=(IP)+16位位移
原理:
1)16位位移=“标号”处的地址-jmp指令后的第一个字节的地址;
2)near ptr指明此处的位移为16位位移,进行的是段内近转移;
3)16位位移的范围为 -32769~32767,用补码表示;
4)16位位移由编译程序在编译时算出。

远转移:jmp far ptr 标号

在这里插入图片描述

转移地址在寄存器中的jmp指令

指令格式:jmp 16位寄存器
功能:IP =(16位寄存器)
举例:
jmp ax
jmp bx
在这里插入图片描述
跳到哪儿由变量定

转移地址在内存中的jmp指令

在这里插入图片描述

jmp 指令小结

在这里插入图片描述

注意:
在这里插入图片描述


四、其他转移指令

jcxz指令

指令格式:jcxz 标号
功能:如果(cx)=0,则转移到标号处执行 ; 当(cx)≠0时,什么也不做(程序向下执行)
当(cx)=0时,(IP)=(IP)+8位位移)
8位位移=“标号”处的地址-jcxz指令后的第一个字节的地址;
8位位移的范围为-128~127,用补码表示;
8位位移由编译程序在编译时算出;

jcxz是有条件转移指令
所有的有条件转移指令都是短转移
对IP的修改范围都为-128~127
在对应的机器码中包含转移的位移,而不是目的地址
例:
在这里插入图片描述

loop指令

指令格式:loop 标号
指令操作:
1)(cx)=(cx)-1;
2)当(cx)≠0时,则转移到标号处执行 ; 当(cx)=0时,程序向下执行
8位位移=“标号”处的地址-loop指令后的第一个字节的地址
8位位移的范围为-128~127,用补码表示
8位位移由编译程序在编译时算出
在这里插入图片描述
在这里插入图片描述

根据位移进行“相对”转移的意义

对 IP的修改是根据转移目的地址和转移起始地址之间的位移来进行
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号
在这里插入图片描述


五、call 指令和 ret 指令

模块化程序设计

C语言中我们可以实现模块化设计
在这里插入图片描述
汇编中也可以实现模块化设计
在这里插入图片描述

call 指令

字面意思:调用子程序
实质:流程转移
call指令实现转移的方法和 jmp 指令的原理相似

格式:call 标号
CPU执行call指令,进行两步操作:
1)将当前的 IP 或 CS和IP 压入栈中;
2) 转移到标号处执行指令。
在这里插入图片描述

call 标号
16位位移=“标号”处的地址-call指令后的第一个字节的地址;
16位位移的范围为 -32768~32767,用补码表示;
16位位移由编译程序在编译时算出。
在这里插入图片描述
在这里插入图片描述

指令“call far ptr 标号”实现的是段间转移

CPU执行“call far ptr 标号”时的操作
1)(sp) = (sp) – 2
((ss) ×16+(sp)) = (CS)
(sp) = (sp) – 2
2) (CS) = 标号所在的段地址
(IP) = 标号所在的偏移地址
“call far ptr 标号” 相当于
push CS
push IP
jmp far ptr 标号
在这里插入图片描述

在这里插入图片描述

转移地址在寄存器中的call指令

指令格式
call 16位寄存器
功能:
(sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(IP) = (16位寄存器)
相当于进行
push IP
jmp 16位寄存器
在这里插入图片描述

转移地址在内存中的call指令

call word ptr 内存单元地址
相当于:
push IP
jmp word ptr 内存单元地址
在这里插入图片描述

call dword ptr 内存单元地址
相当于:
push CS
push IP
jmp dword ptr 内存单元地址
在这里插入图片描述

返回指令:ret 和 retf

在这里插入图片描述

执行过程

在这里插入图片描述


六、call 和 ret 配合使用

具有子程序的源程序的框架

在这里插入图片描述

call 和 ret 配合使用

例:
计算2的N次方,计算前,N的值由CX提供。
在这里插入图片描述
在这里插入图片描述
我们在这里没有设置栈段,这是非常危险的!

为call和ret指令设置栈

这里是引用
在这里插入图片描述


七、乘法:mul 指令

回顾:除法div指令

div是除法指令,格式为:
div 寄存器
div 内存单元
使用div作除法的时候
被除数:(默认)放在AX 或 DX和AX中
除数:8位或16位,在寄存器或内存单元中
结果:…
在这里插入图片描述

用mul指令做乘法

格式:
mul 寄存器
mul 内存单元
在这里插入图片描述

应用案例

在这里插入图片描述


八、汇编语言模块化程序设计

模块化程序设计

调用子程序:call指令
返回:ret指令
子程序:根据提供的参数处理一定的事务,处理后,将结果(返回值)提供给调用者。在这里插入图片描述

参数和结果传递的问题

问题:根据提供的N,计算N的三次方。
考虑:
1)我们将参数N存储在什么地方?
2)计算得到的数值,存储在什么地方?
方案:
用寄存器传递参数
用内存单元进行参数传递
用栈传递参数
在这里插入图片描述

用寄存器来储存参数和结果是最常使用的方法

问题:根据提供的N,计算N的三次方。
考虑:
1)我们将参数N存储在什么地方?
2)计算得到的数值,存储在什么地方?
寄存器传递参数
参数放到 bx 中,即(bx)=N
子程序中用多个 mul 指令计算 N^3
将结果放到 dx 和 ax中:(dx:ax)=N^3
在这里插入图片描述

编程任务:计算data段中第一组数据的 3 次方,结果保存在后面一组dword单元中。
在这里插入图片描述
问题:
如果需要传递的数据有3个、4个或更多,寄存器不够了,怎么办?

用内存单元批量传递数据

方案:
将批量数据放到内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序。
对于具有批量数据的返回结果,也可用同样的方法。

编程任务:
将data段中的字符串转化为大写。
在这里插入图片描述
在这里插入图片描述

用栈传递参数

原理:由调用者将需要传递给子程序的参数压入栈中,子程序从栈中取得参数
任务:计算( a – b ) ^ 3 ,a、b 为 word 型数据。
进入子程序前,参数a、b入栈
调用子程序,将使栈顶存放IP
结果:( dx : ax ) = ( a – b ) ^ 3
例:设 a = 3 、b = 1 ,计算:( a – b ) ^ 3
在这里插入图片描述
在这里插入图片描述
将bp入栈出栈后不改变先前bp的值。在这里插入图片描述
将sp回复。在这里插入图片描述

程序的执行过程中栈的变化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结:参数和结果传递的问题

问题:根据提供的N,计算N的3次方。
考虑:
1)我们将参数N存储在什么地方?
2)计算得到的数值,存储在什么地方?
方案:
用寄存器传递参数
用内存单元进行参数传递
用栈传递参数


九、寄存器冲突问题

引子

在这里插入图片描述
这个12哪来的?
这样写是数出来的,有没有别的办法呢?
C语言中用\0
汇编也可以。在后边加个0,db ‘conversation’,0

编程将data段中的字符串转化为大写

在这里插入图片描述
在这里插入图片描述

在例:将以下字符串转为大写
在这里插入图片描述
写出:
在这里插入图片描述
但是这个代码有一个大问题:
cx既用于循环又用于读取数据-------冲突!!!

寄存器冲突问题的解决

两个可能方案
1)在编写调用子程序的程序时 ,注意看看子程序中有没有用到会产生冲突的寄存器。
如果有,调用者使用别的寄存器;
2)在编写子程序的时候,不要使用会产生冲突的寄存器。
在这里插入图片描述

我们希望
1)编写调用了程序的程序的时候不必关心子程序到底使用了哪些寄存器;
2)编写子程序的时候不必关心调用者使用了哪些寄存器;
3)不会发生寄存器冲突。
在这里插入图片描述

寄存器冲突问题的解决示例

这里是引用
在这里插入图片描述
在这里插入图片描述


十、标志寄存器

8086CPU有14个寄存器:
通用寄存器:AX、BX、CX、DX
变址寄存器:SI、DI
指针寄存器:SP、BP
指令指针寄存器: IP
段寄存器:CS、SS、DS、ES
标志(flag)寄存器:PSW/FLAGS别称:程序状态字
在这里插入图片描述

认识标志寄存器的特殊之处

标志寄存器的结构:
flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。
8086CPU中没有使用flag的1、3、5、12、13、14、15位,这些位不具有任何含义。
在这里插入图片描述

标志寄存器的作用:
用来存储相关指令的某些执行结果
用来为CPU执行相关指令提供行为依据
用来控制CPU的相关工作方式
观察寄存器的值:
在这里插入图片描述
在这里插入图片描述
直接访问标志寄存器的方法
pushf:将标志寄存器的值压栈;
popf:从栈中弹出数据,送入标志寄存器中。

ZF-零标志(Zero Flag)

在这里插入图片描述

ZF标记相关指令的计算结果是否为0;
ZF=1,表示“结果是0 ”,1表示“逻辑真”
ZF=0,表示“结果不是0”,0表示“逻辑假”
例:
在这里插入图片描述
在这里插入图片描述

PF-奇偶标志(Parity Flag)

在这里插入图片描述

PF记录指令执行后,结果的所有二进制位中1 的个数
1的个数为偶数PF=1
1的个数为奇数PF=0
例:
在这里插入图片描述

SF-符号标志(Sign Flag)

在这里插入图片描述

SF记录指令执行后,将结果视为有符号数
结果为SF=1
结果为非负SF=0
例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CF-进位标志(Carry Flag)

在这里插入图片描述

在进行无符号数运算的时候,CF记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值
CF记录指令执行后:
有进位或借位CF = 1
无进位或借位CF = 0
例:
在这里插入图片描述
在这里插入图片描述

OF-溢出标志(Overflow Flag)

在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出。
OF记录有符号数操作指令执行后,
有溢出OF = 1
无溢出OF = 0
例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

综合:一条指令会带来多个标志寄存器的变化

在这里插入图片描述
可通过Debug检验结果:
在这里插入图片描述


十一、带进(借)位的加减法

adc带进位加法指令

adc是带进位加法指令 ,它利用了CF位上记录的进位值。
adc是带进位加法指令 ,它利用了CF位上记录的进位值。
功能:操作对象1=操作对象1+操作对象2+CF
例:adc ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF
实例:
在这里插入图片描述

adc指令应用:大数相加

问题:8086指令提供add指令,完成8位或16位加法,有更大的数相加时,如何做?
32位、64位、24位?
在这里插入图片描述
在这里插入图片描述

128 位数据相加

问题:编写一个子程序,对两个128位数据进行相加。
名称:add128
功能:两个逆序存放的128位数据进行相加
在这里插入图片描述
在这里插入图片描述
数据为128位,需要8个字单元,由低地址到高地址单元,依次存放由低到高的各个字。
分析:
ds:si指向存储第一个数的内存空间
ds:di指向存储第二个数的内存空间
运算结果存储在第一个数的存储空间中。
在这里插入图片描述
在这里插入图片描述
答案是不行的:
sub ax,ax将CF清零
inc di 不会影响进位,add di,2 会影响进位。

sbb 指令

sbb:带借位减法指令
格式:sbb 操作对象1,操作对象2
功能:操作对象1=操作对象1–操作对象2–CF
与sub区别:利用CF位上记录的借位值
比如:sbb ax,bx
实现功能: (ax) = (ax) – (bx) – CF
在这里插入图片描述


十二、cmp与条件转移指令

cmp指令

cmp指令
格式:cmp 操作对象1,操作对象2
功能:计算操作对象1–操作对象2
在这里插入图片描述
应用: 其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
例如:
在这里插入图片描述

无符号数比较与标志位取值

思路:通过cmp 指令执行后相关标志位的值,可以看出比较的结果
指令:cmp ax,bx
在这里插入图片描述

有符号数比较与标志位取值

问题:用cmp来进行有符号数比较时,CPU用哪些标志位对比较结果进行记录?
示例指令:cmp ah,bh
在这里插入图片描述

条件转移指令

套路:
cmp oper1,oper2 ;或者其他影响标志寄存器的指令
jxxx 标号
在这里插入图片描述

条件转移指令的使用

jxxx系列指令和cmp指令配合,构造条件转移指令
不必再考虑cmp指令对相关标志位的影响和jxxx指令对相关标志位的检测
可以直接考虑cmp和jxxx指令配合使用时表现出来的逻辑含义
jxxx系列指令和cmp指令配合实现高级语言中if语句的功能
在这里插入图片描述


十三、条件转移指令的应用

条件转移指令:jxxx——je/jna/jae…
可以根据某种“条件”,决定是否“转移”程序执行流程
“转移”= 修改IP
如何检测条件?
通过检测标志位,由标志位体现条件
条件转移指令通常都和cmp相配合使用,cmp指令改变标志位
例:双分支结构的实现
在这里插入图片描述

应用案例

  • 给出下面一组数据:
  • 在这里插入图片描述
    请编程实现如下统计,用ax保存统计结果
    1)统计数值为8的字节的个数
    2)统计数值大于8的字节的个数
    3)统计数值小于8的字节的个数

1)编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个和8相等的数就将ax的值加1。
在这里插入图片描述
2)初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个大于8的数就将ax的值加1。
在这里插入图片描述
3)初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个小于8的数就将ax的值加1。
在这里插入图片描述


十四、DF标志和串传送指令

问题分析

编程:将data段中的第一个字符串复制到它后面的空间中。
在这里插入图片描述
在这里插入图片描述
这是我们之前写过的代码,在这情况下能在简洁吗?

DF标志和串传送指令

在这里插入图片描述

DF-方向标志位(Direction Flag)
功能
在串处理指令中,控制每次操作后si,di的增减。
DF = 0:每次操作后si,di递增
DF = 1:每次操作后si,di递减
对DF位进行设置的指令
cld指令:将标志寄存器的DF位设为0(clear)
std指令:将标志寄存器的DF位设为1(setup)

串传送指令1:movsb
功能:(以字节为单位传送)
1)((es))*16+(di))=((ds)*16+(si))
2) 如果DF = 0则: (si) = (si) + 1 ; (di) = (di) + 1
如果DF = 1则:(si) = (si) - 1 ; (di) = (di) - 1
串传送指令2:movsw
功能:(以字为单元传送)
1)((es)*16+(di))=((ds)*16+(si))
2)) 如果DF = 0则: (si) = (si) + 2 ; (di) = (di) + 2
如果DF = 1则: (si) = (si) - 2 ; (di) = (di) - 2
在这里插入图片描述

rep指令

rep指令常和串传送指令搭配使用
功能:根据cx的值,重复执行后面的指令
用法:
在这里插入图片描述
在这里插入图片描述

应用实例

任务:用串传送指令,将F000H段中的最后16个字符复制到data段中。(F000H段的最后一个字符的位置:F000:FFFF)
data segment
db 16 dup (0)
data ends
在这里插入图片描述


总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

这篇关于【汇编语言】流程转移和子程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935259

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

火语言RPA流程组件介绍--浏览网页

🚩【组件功能】:浏览器打开指定网址或本地html文件 配置预览 配置说明 网址URL 支持T或# 默认FLOW输入项 输入需要打开的网址URL 超时时间 支持T或# 打开网页超时时间 执行后后等待时间(ms) 支持T或# 当前组件执行完成后继续等待的时间 UserAgent 支持T或# User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真

C++/《C/C++程序编译流程》

程序的基本流程如图:   1.预处理        预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。 读取C/C++源程序,对其中的伪指令(以#开头的指令)进行处理将所有的“#define”删除,并且展开所有的宏定义处理所有的条件编译指令,如:“#if”、“

笔记本电脑的具体选购步骤流程

2.1 笔记本电脑的具体选购步骤流程   关于笔记本电脑的选购,一直是热点话题。不管是新手还是老前辈,选购前,总是要先上网查一查,汇总一些信息或经验。因为选购一台笔记本电脑,从它的配置、外观到做工等很多方面都需要考量,所以挑一台自己喜欢的、适合自己的笔记本电脑也是一件很费脑筋的事情。本节将一些选购笔记本电脑的经验进行了总结,供广大读者选购笔记本电脑时参考。   笔记本电脑选购流程如下

基于微信小程序与嵌入式系统的智能小车开发(详细流程)

一、项目概述 本项目旨在开发一款智能小车,结合微信小程序与嵌入式系统,提供实时图像处理与控制功能。用户可以通过微信小程序远程操控小车,并实时接收摄像头采集的图像。该项目解决了传统遥控小车在图像反馈和控制延迟方面的问题,提升了小车的智能化水平,适用于教育、科研和娱乐等多个领域。 二、系统架构 1. 系统架构设计 本项目的系统架构主要分为以下几个部分: 微信小程序:负责用户界面、控制指令的