汇编语言程序设计 pdf里面各段存放的是什么啊?

汇编语言学习第六章-包含多个段的程序
在前面的介绍的程序中只有一个代码段。那么如果我们需要将代码,数据分别存储在不同的内存空间应该怎么办呢?我们知道我们不可能随便使用任何一段内存空间,因为我们这段内存地址空间可能存储着非常重要的内容。其实,这只是我们考虑的太多啦,一旦我们将程序载入内存后,操作为我们分配的用于程序运行的内存空间都是安全的,绝对不会与其他程序的内存空间相重叠的。
往往程序获取内存有两种方式:一种是在程序载入内存的时候操作系统已经分配好的内存空间,另外一种是我们在程序运行的时候需要申请额外的内存空间进行相关的存储。(这里第二种方式为动态分配我们暂时不讨论)
前面我们已经有过这样的经验,我们在程序中定义一个段,然后当程序载入内存的时候,操作系统会自动为我们分配一个内存段用于存储。我们从另一方面来说说这个问题,如果我们程序中不仅包括代码,还有数据,甚至还有后面学习到的栈空间。我们如果把这些数据都保存到一个段,那么显然在程序设计和使用上难免逻辑不够清晰,往往我们都是在程序中定义不同的段来进而在内存空间中分别存储代码,数据和栈。
6.1在代码段中使用数据
这里我们先考虑这样一个问题,我们需要计算如下八个数的和:
0123h、0456h、0789h、0abch、0defh、0fedh、0cbah、0987h
这里我们要解决这个问题需要将上面这八个数据依次存储到某个寄存器中,然后再用某个寄存件保存累加结果进行累积。但是这样显然不够smart,如果可以用循环就最好了。那么问题来了,既然要用循环我们就需要把这8个数据依次存储到内存中的一段连续区域中。那么如果找到一段连续的内存空间呢?我们可以在程序中定义一段这8个数据,然后当程序经过编译链接成可执行文件载入到内存后,这8个数据就存储在了连续的内存空间了,接下来我们就可以使用循环进行累积求和了。
程序代码如下:
程序主要解释,其中dw为定义字型数据 define word,这里一共定义了8个字型数据。一共16个字节。 bx用于循环的索引,每次循环内存向后移动两个字节,ax为用于存储累积结果,cx用于循环计数器,初始值为8,每循环一次cx=cx-1.程序很简单,相信大家都能理解。这里特别说明,我们定义了一个代码段code。 因为dw存储在代码段的最开始位置,所以第一个字型数据的内存偏移定义为0.所以其实际内存地址为cs:0 紧接着0456h在其后的两个字节为cs:2.
接下来我们将该程序保存为vpeot.asm同时编译链接为vpoet.exe(上图代码中mov ax,4c00h忘记加逗号了,囧),然后再用debug工具加载该程序,如下:
从上图中可以看到cs=14FB,可以知道程序是从CS:0000即14FB:0000开始执行的。我们用u命令打印程序指令,发现的确是从14FB:0000开始执行的。然而前面的的一部分并非程序真正的指令,我们可以大胆猜测前面的内容为存储我们定义的dw数据的指令,现在我们使用d命令查看14FB:0000的内存内容。
可以看出从内存14FB:0000开始的16个字节为我们定义的8个字型数据。
那么如果要查看实际的汇编指令需要从14FB:0010开始查看:
这些对了吧。程序被加载后,整个程序的前16个字节为我们定义的8个字型数据。后面的才为我们的汇编指令。
那么如果我们想执行我们的汇编指令,只需要将寄存器IP的值设为0010即可。&
这里还有一个问题就产生了,如果我们不是使用debug工具来改变IP而是直接将程序载入内存中,程序的入口地址并非我们的汇编指令,怎么办呢?
我们可以为程序增加一个标号来标示程序的入口,比如:
这里,我们在第一句汇编指令前面加上了一个标号start同时在伪指令end后也加上了start 这里的start就标示了程序的入口,表明一旦程序载入内存后,CS:IP就会指向第一条指令mov bx,0 我们可以再次编译链接生成exe然后通过debug工具加载到内存中来证实这一点。
先看我们看到程序的入口已经指向了第一条指令,就不需要我们像之前那样更改IP的地址了。
6.2在代码段中使用栈
同样先看一个问题,有8个数据存储在内存的一段连续的空间中。
0123h、0456h、0789h、0abch、0defh、0fedh、0cbah、0987h
我们需要实现这8个数据的逆序存放。
这个问题的思路是,假设这8个数据存储在CS:0~CS:F这段内存空间中,我们可以利用栈存储空间的特点,将这8个字型数据依次压入栈的内存空间中,然后依次弹出到这CS:0~CS:F这段内存空间中,便可以显示数据的逆序存放。这种思路需要我们在程序中定义一段内存空间作为栈空间使用,实现代码如下:
assume cs:code
code segment
dw h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
start:mov ax,cs
mov sp,30h
s:push cs:[bx]
s0:pop cs:[bx]
mov ax,4c00h
这里mov sp,30h需要注意,因为我们在程序的开始首先定义了8个字型用于存储需要逆序存储的数据,同时分配了16个字型的数据用于栈空间使用,所以一共有24个字型,即48个字节的存储空间。所以SP指向栈顶的地址为:SS:IP=CS:30H。
接下来我们编译链接该程序,同时debug加载到内存中,如下所示:
可以看出汇编指令的确是从CS:0030开始。
6.3将数据、代码、栈放入不同的段
前面的程序中我们都是将数据,代码,栈放到一个栈空间中。这样的缺陷就是程序的逻辑不够清晰,还有一个问题是如果代码数据以及栈空间的大小超过一个段的大小,显然他们就不能被放到一个段中了。所以在实际的程序设计中,我们往往将代码,数据以及栈分别定义到不同的段空间中。
我们还是用6.2的问题来进行描述,这次我们将代码,数据,栈空间分配到不同的段中,程序如下:
assume cs:code,ds:data,ss:stack
data segment
dw h,0789h,0abch,0defh,0fedh,0cbah,0987h
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends
code segment
start:mov ax,stack
mov sp,20h
mov ax,data
s:push [bx]
s0:pop [bx]
mov ax,4c00h
关于程序的说明:
1.定义多个段的方法与前面定义一个段的方法相同,不同的段有不同段名。
2.对段名的引用。既然已经定义了不同的段,那么如何通过段名来访问呢。实际上段名代表了该段的段地址。比如假设data段中的数据0abch的地址为data:6,要将该地址的内存传入bx:
mov ax,data
mov bx,ds:[6]
3.代码段,数据段,栈段的由我们安排。我们定义了三个段名data,code,stack并非是存储就代表data必须存储数据,code必须存储代码。我们可以把data用于存储代码,code用于存储数据都是可以的。 另外assume cs:code,ss,stack,ds:data并非是这样关联后cs就指向了代码段,或者说ss指向了栈段。而这里只是编译器让我们将code段与cs相关联,即把code段的段地址存入cs。CPU如何处理我们定义段的内容,是当做指令执行还是数据访问,这完全由汇编程序本身决定,也由cs:ip,ds,ss:sp的值来确定的。
OK,关于本章的内容就介绍到这里了。汇编语言程序设计习题 答案_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
汇编语言程序设计习题 答案
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
还剩8页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢匿名用户不能发表回复!|汇编语言之内存访问,程序执行
&从访问内存的角度继续学习汇编语言。
&1.字(Word)与字长:字是指在计算机中作为一个整体被存取、传送、处理的一组二进制数。一个字的位数(即字长)是计算机系统结构中的一个重要特性。字长是由CPU的类型所决定,不同的计算机系统的字长是不同的,常见的有8位、16位、32位、64位等,字长越长,计算机一次处理的信息位就越多,精度就越高,字长是计算机性能的一个重要指标,目前主流微机正在由32位机向64位机转变。
& 注意字与字长的区别,字是单位,而字长是指标。
机器的字长也会影响机器的运算速度。倘若CPU字长较短,又要运算位数较多的数据,那么需要经过两次或多次的运算才能完成,这样势必影响整机的运行速度。
  机器的字长对硬件的造价也有较大的影响。它将直接影响加法器(或ALU),数据总线以及存储字长的位数。所以机器字长的确不能单从精度和数的表示范围来考虑。
为了适应不同的要求及协调运算精度和硬件造价间的关系,大多数计算机均支持变字长运算,即机内可实现半字长、全字长(或单字长)和双倍字长运算。
&2.内存中字的存储,例如要在0地址处开始存放H),则高位对应高地址,低位对应低地址。左面位的是高位,数字大的是高地址。
在8086CPU中,因为一个字等于两个字节,所以任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个字节单元,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。比如上图中,可以把0和1分别看成单独的,也可以看成一个地址为0的,值是4E20H的字单元。
&3.DS和[address]
&CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址。内存地址同样是由段地址和偏移地址组成的。8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。例如我们要读取10000H单元的内容,可以用如下程序段进行,这就可以把1000:0中的数据读取到al中。
& & &第三行中的[
]说明操作对象是一个内存单元,[
]中的0说明这个内存单元的偏移地址是0,它的段地址默认放在ds中。前两行把内存单元的段地址1000放入ds中,为什么不能直接把1000送到ds,而要经过bx过渡呢?因为8086CPU不支持将数据直接送入段寄存器的操作,而ds是一个段寄存器,这是硬件设计的问题。必须是数据-&通用寄存器-&段寄存器。
将数据从寄存器送入内存单元,刚好相反的操作。
&栈是一种具有特殊访问方式的存储空间,它的特殊性就在于,最后进入这个空间的数据最先出去,也就是所谓的后进先出。
入栈:将一个新的元素放到栈顶
出栈:从栈顶取出一个元素。
&如今的CPU中都有栈的设计,而8086CPU也提供了相关指令来以栈的方式访问内存空间,这意味着,我们在基于8086CPU编程的时候,可以将一段内存当做栈来使用。
PUSH是入栈,push
ax的意思是,将寄存器ax中的数据送入栈中
POP指令是出栈&pop
ax的意思是,从栈顶取出数据放入ax中
push和pop也可以对段寄存器进行操作,入栈出栈都是以字为单位进行的。
&那么CPU如何知道一段内存空间是被当作栈来使用的?执行push和pop的时候,cpu又是如何知道哪个单元是栈顶单元的?答案就在于,8086CPU中的段寄存器SS用来存放栈顶的段地址,寄存器SP存放栈顶的偏移地址。当一个栈初始化还没有值的时候,sp指向的是栈底的下一个单元,然后在执行第一次push之后的任意时刻,
SS:SP指向栈顶元素,入栈的时候,sp首先减去2,然后放数据,当出栈的时候,先把数据出去,sp再加2。
ax命令的执行过程
&1&将SS:SP指向的内存单元处的数据送入ax中
&2&SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
&3&出栈后,元素的数据依然是存在的,只不过不在栈里面了,这个过程是复制粘贴,而不是剪切粘贴,只有当再次执行push之后,新的数据才会把旧数据覆盖掉。
&6.栈顶越界的问题。
&当栈满的时候再使用push,或者栈空的时候再使用pop,都会发生栈顶越界问题。栈顶越界是比较危险的,我们将一段空间安排为栈,那么栈之外的空间中很可能存放了具有其他用途的数据、代码等,这些数据,代码可能是我们自己写的程序中的,也可能是其他程序中的,如果把这些不属于我们掌握的代码进行了改写,可能会引发一连串的错误。我们依靠SS和SP可以保证在入栈和出栈的时候找到栈顶,可如何能够保不越界?
&8086CPU不能保证对栈的操作不越界,它只知道栈顶在何处,而不知道我们安排的栈空间有多大,这就好像,cpu知道当前执行的指令在何处,但是不知道我们要执行多少指令。所以结论就是,我们在编程的时候只能自己操心越界问题。
&7.栈与内存
&栈空间当然也是内存空间的一部分,它只是一段可以以一种特殊的方式进行访问的内存空间,目的就是为了临时存放东西的。
&8.我们必须非常清楚,入栈出栈和mov是不同的,执行mov指令只需要一步操作,就是传送,而入栈出栈都是两步。还要注意,push和pop修改的都是sp的内容,也就是说,对于8086来说,栈顶的最大变化范围就是0-FFFFH,最大64KB。
&9.栈段。我们可以将长度为N(N&=64KB)的一组地址连续、起始地址为16的倍数的内存单元当做栈来使用,从而定义了一个栈段。当然,将一段内存当作栈段,仅仅是我们在编程时的一种安排,cpu知道的只是栈顶。
&如果我们把10000H-1FFFFH看作栈段,初始状态是空的,此时SS=1000,那么SP的值应该是多少?由地址范围我们知道,这时候栈的空间是64KB,已经达到最大了,如果再加上1,那就溢出抛弃了,所以此时SP的值就是0。
&所以刚开始初始化的时候,SP的值是0,然后一直压栈,到满的时候SP的值又回到了0,如果再次压栈,栈顶将环绕,覆盖了原来栈中的内容。
&10.一段内存,可以既是指令的存储空间,又是数据的存储空间,同时还是栈空间,也可以什么都不是,关键在于CPU中寄存器的设置,在于CS,IP,SS,SP,DS的指向。
&11.可执行文件中包含两部分内容:
&1&程序(从源程序中的汇编指令翻译过来的机器码)和数据(源程序中定义的数据)
&2&相关的描述信息,比如说程序要占多少内存空间等等。
&12.执行可执行文件中的程序
&操作系统按照可执行文件中的描述信息,将可执行文件中的机器码和数据加载到内存中,并进行相关的初始化(比如设置CS:IP指向第一条要执行的命令),然后由cpu执行程序。
&13.汇编指令就是有对应机器码的指令,可以被编译为机器指令,最终被cpu执行。
伪指令是没有对应机器码的指令,它是由编译器来执行的,编译器根据伪指令来进行相关的编译工作。
segment和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时,必须要用到的一对伪指令。Segment和ends的作用是定义一个段,segment说明一个段开始,ends说明一个段结束。一个段必须有一个名称来标识,使用格式为
end是整个汇编程序结束的标记,编译器在编译汇编程序的过程中,如果碰到了伪指令end,就结束对源程序的编译。如果程序写完了,要在结尾处加上伪指令end,否则编译器不知道程序在什么地方结束。
assume的含义为“假设”,是寄存器与段的关联假设,它假设某一个段寄存器和程序中的某一个用segment……ends定义的段相关联。通过assume说明这种关联,在需要的情况下,编译程序可以将段寄存器和某一个具体的段相联系。
一个标号指代了一个地址,上图中的codesg放在segment前面,作为一个段的名称,这个段的名称最终将被编译,链接程序处理为一个段的段地址。
&14.一个汇编程序是由多个段组成的,这些段被用来存放代码,数据,或当作栈空间来使用。一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。
&15.我们可以将源程序文件中的所有内容称为源程序,将源程序中最终由cpu执行处理的指令或数据称为程序。程序最先以汇编指令的形式存在于源程序中,经编译,连接后转变为机器码,存储在可执行文件中。
&16.DOS中的程序返回
&DOS是一个单任务操作系统,假如一个程序b在可执行文件中,如果它想运行,必须有一个正在运行的程序a,将b从可执行文件中加载入内存后,将cpu的控制权交给b,b才能够运行,b开始运行后,a暂停运行,叫做挂起。当b运行完毕后,应该将cpu的运行权交还给使它得以运行的程序a,此后,a继续运行。
&上面提到的,b把运行权交还给a的这个过程就叫做程序返回,具体的实现方式是在程序的末尾添加返回的程序段,下面这两条指令就是程序返回。
&17.语法错误和逻辑错误
&语法错误是程序在编译时被编译器发现的错误,比较容易发现,而逻辑错误是不能被编译器判断出来的,但会在运行的时候发生,避免逻辑错误在于经验的累计。
&18.汇编文件的扩展名
&扩展名有.asm和.s两种,.asm是dos和win下常见的源程序扩展名,.s是linux内核源程序中用的扩展名,它们的本质都是文本文档,没区别。有些linux下的编译器在产生汇编码输出的时候,也会生成.s的扩展名
&19.自己写一个简单的汇编文件,用.asm后缀名。
&可以使用masm.ext和link.ext分别来编译连接源文件,也可以使用ml.ext直接编译连接,两步合成一步。这段程序没有使用显示器输出任何信息,只是将数据送入寄存器,还有加法操作,所以我们不能从屏幕上看到效果,程序执行只是闪动了一下,然后就返回了,屏幕上再次出现了操作系统的提示符。
&20.编译和连接
&编译就是将源程序转化成机器码的过程。连接的作用有以下几个
&1&一个源程序编译后,得到了存有机器码的目标文件,目标文件中有些内容还不能用来生成可执行文件,连接文件将这些内容处理为最终的可执行信息。
&2&当源程序很大的时候,可以将它分为多个源程序文件来编译,每个源程序编译成目标文件后,再用连接程序把它们连接在一起,生成一个可执行文件。
&3&程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件。
&21.操作系统的外壳——shell
&操作系统是由多个功能模块组成的庞大、复杂的软件系统。任何通用的操作系统,都要提供一个称为shell(外壳)的程序,我们使用这个程序来操作计算机系统工作。
&DOS中有一个程序commond.com,这个程序在DOS中称为命令解释器,也就是DOS系统的shell。
&22.比如我们在DOS中执行a.exe,是正在运行的shell将a.exe中的程序加载入内存,然后shell设置CPU的CS:IP指向程序的第一条指令,即程序的入口,从而使程序得以运行。程序运行结束后,返回到shell中,cpu继续运行shell。
&23.exe文件中的程序的加载过程,PSP是DOS用来和程序进行通信的手段。
&24.如果我们在DOS中调用debug
a.exe,则是先由shell加载debug,然后debug再加载a.exe,退出的时候先返回到debug,最后返回到shell,这也比较容易理解。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。在电子工程世界为您找到如下关于“汇编程序”的新闻
汇编程序资料下载
语言语句格式 4. 3. 1 ARM汇编语言中的符号 4. 3. 2 ARM汇编语言中的表达式 4. 4 ARM汇编语言程序格式. 4. 4. l 汇编语言程序格式 4. 4. 2 汇编语言子程序调用 4. 5 ARM汇编编译器的使用 4. 6 汇编程序设计举例 4. 6. 1 ARM中伪操作使用实例 4. 6. 2 ARM中汇编程序实例
第5章 ARM存储系统 5. 1 ARM存储系统概述 5....
语言伪指令 4. 3 ARM汇编语言语句格式 4. 3. 1 ARM汇编语言中的符号 4. 3. 2 ARM汇编语言中的表达式 4. 4 ARM汇编语言程序格式. 4. 4. l 汇编语言程序格式 4. 4. 2 汇编语言子程序调用 4. 5 ARM汇编编译器的使用 4. 6 汇编程序设计举例 4. 6. 1 ARM中伪操作使用实例 4. 6. 2 ARM中汇编程序实例 第5章 ARM存储系统 5....
7.4.2 定义各类寄存器名称的伪指令184
7.4.3 数据定义伪指令187
7.4.4 控制程序流向的伪指令196
7.4.5 其他伪指令201第8章 ARM系统设计和程序设计8.1 关于ARM处理器,我们学到了什么?207
8.2 程序设计的几个问题209
8.3 ARM指令和 Thumb指令的兼容性214
8.4 汇编程序规则221
8.4.1 组成222
电缆环境下的程序调试
9.4.4 Linux环境下的gdb程序调试
9.5 ARM汇编语言与C语言混合编程
9.5.1 基本的ATPCS
9.5.2 汇编程序中调用C程序
9.5.3 C程序中调用汇编程序
9.5.4 C程序中内嵌汇编语句
9.5.5 从汇编程序中访问C程序变量
思考题与习题
第10 章 Bootloader 设计基础...
本章的主要内容:
ARM编译器所支持的伪指令
汇编语言的语句格式
汇编语言的程序结构
相关的程序示例4.1
ARM汇编器所支持的伪指令
在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作...
AD转换的汇编程序AD转换的汇编程序AD转换的汇编程序...
及字符串函数库12.9 串行通信类函数库第13章 如何设计模块化程序13.1 基本概念13.2 硬件结构13.3 软件结构13.3.1 模块化13.3.2 流程图13.3.3 程序列表与说明13.3.4 汇编程序列表13.4 开发环境的操作第14章 模块化程序设计的应用(一)14.1 基本概念14.1.1 INPUT 14.1.2 OUTPUT14.1.3 蜂鸣器14.2 硬件结构14.3 软件结构...
功能的总代码生成量比使用汇编语言略高 20% 任何一款编译器都不会比一个有经验的汇编语言程序员编写的汇编程序效率高, 但是写一个 好的 C 程序然后转换为高效的汇编程序比直接写高效的汇编程序就容易多了. 综上所述, 无论是采用 C 语言还是汇编语言都各有其利弊.我们既不推荐在学习与开发嵌 入式软件过程中完全采取汇编语言(因为汇编语言对一个不懂硬件的新手来说,是需要一定 的时间才能上手的),也不赞同...
基本概念、ARM处理器原理及应用、ARM汇编程序设计、ARM处理器C语言程序设计、ARM中断处理、无操作系统下ARM接口驱动程序设计以及嵌入式操作系统基本原理等内容。本书在内容编写上按由浅入深、从易到难的顺序,构建了完整的嵌入式ARM底层相关开发知识体系。第1部分:精要介绍了,与该知识点相关的基础理论;第2部分:详细介绍了应用平台ARM处理器与之相关的知识点内容;第3部分:详细介绍了ARM实例开发程序...
汇编程序集,包含很多一般的汇编程序...
汇编程序相关帖子
end of the
&&//context restore. Now induce a context save.
&&void CS_contextSave(void);
&&CS_contextSave();
关键在于 CS_contextSave() 的实现,它是 context_switch.s 的汇编程序...
时候各个字
时候:例如两个连续字ox1000 ox1004) 写汇编程序时候,下一个字也需要+4,但写 C语言时候,int 型,+1就是加4
但是,在Tiger SHARC中,虽然也是32位机,但内存是地址是按字组织的,查看内存时,连续的字地址相差...
多绕组、多种电压输出。
3、支持多种整流方式输出。
4、软件计算线圈匝数时自动加入负载压降、整流压降等。
5、附带大量常用数据资料,方便用户查询
8.ACEx线路仿真套件包括:
ACEx线路仿真板
开发工具向导
ACEx交叉汇编程序
ACEx仿真/模拟软件
ACEx程序设计
ACE1101和ACE1202数据库
GNU Binutils工具集与GCC的关系 GCC 是"compiler collection",包括C编译器、C++编译器、Fortran编译器等等。Binutils 是GNU另外一个软件项目,包含汇编工具(as), 链接工具(ld), 库管理工具(ar), 目标文件查看(objdump)等等。GCC需要依赖Binutils才能工作,不然它只能做到比如C程序编译成汇编程序这一步...
我更喜欢RSIC架构的,指令少,单条指令可以是14-16位不等,在汇编程序中便于发挥。
楼主可以自己多了解多比较,国产的MCU还有海尔、合泰、应广等,都可以看看
再说一件题外的事情
关于这家公司的供货能力和口碑
就上面一个兄弟提到的 stc 8脚,不知道现在有没出新的系列,如果没有,那指的应该是当年的 stc15系列
2010年时,我对这个系列是很感兴趣的,当时一直等着它推出,我玩玩...
汇编程序视频
你可能感兴趣的标签
热门资源推荐}

我要回帖

更多关于 汇编语言程序设计 pdf 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信