<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://www.gentoo-zh.org/extern.php?action=feed&amp;tid=109&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Gentoo中文社区 / 汇编学习路]]></title>
		<link>https://www.gentoo-zh.org/viewtopic.php?id=109</link>
		<description><![CDATA[汇编学习路 最近发表的帖子。]]></description>
		<lastBuildDate>Thu, 18 Aug 2022 12:50:47 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[汇编学习路]]></title>
			<link>https://www.gentoo-zh.org/viewtopic.php?pid=115#p115</link>
			<description><![CDATA[<p>汇编学习路<br />&#160; &#160; 我是为学C来学汇编预热下的，教材是王爽的那本，之所以把学习笔记写这里，一方面给自己留点纪念，更重要的是希望有老鸟来看看来指正一下，因为是自学，没老师没同学，所以错了可能自己也不知道。<br />&#160; &#160; 第一章1.1——1.10<br />计算机有3中语言，机器语言、汇编语言和N多的高级语言。<br />机器语言就是一条条机器指令的集合。<br />汇编语言的主体是汇编指令。<br />汇编指令和机器指令本质是一样的，差别在于指令的表示方法上，一个茴字有几种下法的问题，本质都是茴这个字。<br />寄存器简单讲是CPU中可以存储数据的器件。寄存器和CPU的关系可以近似的看做是内存和PC机的关系。<br />一个CPU有多个寄存器，AX、BX只是其中2个不同寄存器的代号。<br />计算机可以识别的只有二进制和逻辑运算符，所以一个汇编指令要执行必须由编译器将汇编指令翻译成机器指令发送给计算机。<br />汇编语言由3类指令构成：汇编指令（机器指令的另一种写法）<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;伪指令和其他符号（这2中由编译器翻译成逻辑运算符交给计算机）<br />CPU要工作必须有指令和数据，指令和数据在存储器中存放。<br />CPU无法直接读取磁盘的数据，需先调入内存中，再由内存和CPU进行数据交换。<br />存储在计算机中的一切数据都是二进制信息，指令或数据只是应用上的概念。<br />存储器划分成若干个单元，从0开始顺序编号。<br />一个存储单元存放一个字节。一字节有8个二进制位。<br />1KB = 1024B&#160; &#160; 1MB = 1024KB&#160; &#160; 1GB = 1024MB&#160; &#160; 1T = 1024GB<br />CPU要进行数据的读写，必须和外部器件（芯片）进行3类数据的交换：<br />存储单元的地址（地址信息）。<br />器件的选择，读或写的命令（控制信息）。<br />读或写的数据（数据信息）。<br />换成江湖上的说法，要知道目标是谁，位置在哪里，是打死还是打残。<br />CPU和外部芯片依靠总线连接并进行数据交换。<br />总线有3类：地址总线、数据总线和控制总线。<br />计算机存放的都是二进制信息，依靠3种总线区别数据或指令。从地址总线传输的都是地址信息，从数据总线传输的都是数据信息，从控制总线传输的都是控制命令。<br />一个CPU有N根地址总线，则可以说这个CPU的地址总线宽度为N，最多可以寻找2的N次方个地址单元。<br />数据总线决定了CPU的速度，一根地址总线一次可以传送一位二进制数据。16根地址总线则可以一次传送16位二进制数据，即2个字节。<br />控制总线是一些不同控制线的集合，控制总线的宽度决定了CPU对外部器件的控制能力。<br />监测点1.1<br />（1）寻址能力位8KB，即8192b，开平方之后得出结果为13.<br />（2）1KB有1024个存储单元，编号从0到1023.<br />（3）1KB的存储器可以存储1024*1024个位，1024个byte。<br />（4）1KB是1024个byte,1MB是1024*1024byte，1GB是1024*1024*1024byte。结果懒的算了。<br />（5）8080的地址总线宽度为16，寻址能力则为2的16次方字节，8088的地址总线宽度为20，则寻址能力为2的20次方字节。其余类推，换算就不算了，麻烦。<br />（6）8080的数据总线宽度为8，则一次可以传输8位二进制数据，即1B。8086为16根，则可以传输16位二进制数据，即2B.其余类推。<br />（7）8086数据总线宽度为16，则一次可以传输16位二进制数据，即2B。从内存中读取1024字节，至少要读512次。<br />&#160; &#160; &#160;80386数据总线宽度为32，则一次可以传输32位二进制数据，即4B。从内存中读取1024字节，至少要读256次。<br />（8）在存储器中，数据和程序以二进制形式存放。<br />2012年8月17日23:19:12，还早，继续奋斗。</p><p>第一章1.11——1.15<br />CPU可寻到的内存单元就构成这个CPU的内存地址空间。<br />随机存储器从读写属性分为：随即存储器RAM和只读存储器ROM。<br />随机存储器可读可写，但断电后存储内容消失。<br />只读存储器只能读不能写，断电后不会丢失存储内容。<br />从功能划分：<br />主随机存储器一般存放供CPU使用的大部分程序和数据，包括装在主板上的RAM（CPU二级缓存之类）和插在扩展插槽上的RAM（内存条）。<br />装有BIOS的ROM。如主板上ROM的系统BIOS，显卡上ROM的BIOS.<br />某些接口卡需要对大批量输入输出数据进行暂时的存储，也装有RAM。如显卡的RAM，显存。<br />像显存中写入任何数据都将显示在显示器上。<br />CPU将各个存储器看做一个逻辑整体，每个存储器在逻辑整体中占有一段地址。CPU向某段地址进行读写数据，实际上就是对该地址对应的存储器进行数据读写。<br />内存地址空间的大小受CPU地址总线宽度的限制，而CPU将所有的存储器看做一个逻辑整体，而这个逻辑整体实际上就是CPU的内存地址空间。所以我们所能利用的容量便受它控制，对于一个内存大小只有1MB的CPU来说，即使插上一个1G的RAM也只能用到1MB.<br />2012年8月18日0:13:54</p><p>第二章2.1——2.3<br />CPU由运算器、控制器、寄存器组成。依靠内部总线连接。<br />运算器进行信息处理，寄存器进行信息存储，控制器控制各个器件运行。<br />8086CPU有14个寄存器，每个寄存器都是16位。可以存放2个字节。<br />AX、BX、CX、DX是4个通用寄存器，存放一般性数据。<br />N位寄存器所能存储的最大值为2的N次方减1。（好像是这样，但原理不太明白，先跳过）<br />8088CPU寄存器是8位，为保证兼容，8086CPU的4个通用寄存处可以分成2个独立使用的8位寄存器。如AX可分为AH(高位)和AL(低位)。<br />1个字节（byte）由8个二进制位组成，可以存放在8位寄存器中。<br />1个字（word）由2个字节组成，分为高位字节和低位字节，分别存放在16位寄存器的高位寄存器和低位寄存器中。<br />4E20H 十六位进制&#160; &#160; 1000 十进制&#160; &#160; 01110010B 二进制<br />mov ax, 18&#160; &#160; 将18送人寄存器ax<br />mov ah, 78&#160; &#160; 将78送入寄存器ah<br />add ax, 8&#160; &#160; &#160;将寄存器ax中的值加上8再存放到ax<br />mov ax, bx&#160; &#160; 将寄存器bx中的值存放到ax<br />add ax, bx&#160; &#160; 将寄存器ax中的值和bx的值相加，再存放到ax中<br />汇编不区分大小写<br />add ax, bx 等同于 ADD AX, BX<br />在进行数据传送或运输时，要注意指令的两个操作对象的位数应当是一致的。<br />检测点2.1<br />mov ax, 62627&#160; &#160; ax = F4A3H&#160; （62627是十进制，转换成十六进制位F4A3H）<br />mov ah, 31H&#160; &#160; &#160; ax = 31A3H&#160; （指令的意思是将31H送到AX的高8位寄存器AH中，所以结果为31A3H）<br />mov al, 23H&#160; &#160; &#160; ax = 3123H&#160; &#160;(同上，将23H送到AX的低8位寄存器AL中，所以结果为3123H)<br />add ax, ax&#160; &#160; &#160; &#160;ax = 6246H&#160; &#160;(将AX的值加上AX的值再存放到AX中)<br />mov bx, 826CH&#160; &#160; bx = 826CH&#160; &#160;（将826CH存放到BX中）<br />mov cx, ax&#160; &#160; &#160; &#160;cx = 6246H&#160; &#160;(将AX的值存放到CX中)<br />mov ax, bx&#160; &#160; &#160; &#160;ax = 826CH&#160; &#160;(将BX的值存放到AX中)<br />add ax, bx&#160; &#160; &#160; &#160;ax = 04D8H&#160; &#160; (指令的意思是把BX的值加上AX的存放到AX中，结果为104D8H，由于AX是16位寄存器，只能存放4位16进制数，故而结果为04D8H)<br />mov al, bh&#160; &#160; &#160; &#160;ax = 0482H&#160; &#160; (指令的意思是将BH的值存放到AL中，所以结果为0482H)<br />mov ah, bl&#160; &#160; &#160; &#160;ax = 6C82H&#160; &#160; (指令的意思是将BL的值存放到AH中，所以结果为6C82H)<br />add ah, ah&#160; &#160; &#160; &#160;ax = D882H&#160; &#160; (指令的意思是将AH的值加上AH的值存放到AH中，所以结果为D882H)<br />add al, 6&#160; &#160; &#160; &#160; ax = D888H&#160; &#160; (指令的意思是将AL的值加6存放到AL中，所以结果D888H)<br />add al, al&#160; &#160; &#160; &#160;ax = D810H&#160; &#160; (指令的意思讲AL的值加AL的值存放到AL中，由于AL为8位寄存器，而结果为110H，所以AX=D810H)<br />mov ax, cx&#160; &#160; &#160; &#160;ax = 6246H&#160; &#160; (将CX的值存放到AX中)</p><p>第二章2.4——<br />CPU访问内存单元需要给出内存单元的地址。<br />对CPU而言，将所有的内存单元看做一个逻辑线性整体。每个内存单元都有一个唯一的物理地址。<br />CPU只能通过地址总线将物理地址送入寄存器。<br />8086CPU为16位CPU,具有3方面特性：<br />运算器一次最多可以处理16位的数据<br />寄存器的最大宽度为16位（指通用寄存器）<br />寄存器和运算器之间的通路位16位。<br />8086CPU有20位地址总线，可以传送20位地址，寻址能力为2的20此方，1MB。<br />8086CPU为16位结构，在内部一次性处理、传输、暂时存储的地址为16位，寻址能力只有2的16此方，64KB。<br />为充分利用20位地址总线，8086CPU采用在内部用2个16位地址合成20位地址的方法。<br />公式&#160; &#160;物理地址 = 段地址*16 + 偏移地址&#160; （这里的地址均为16进制）<br />例：段地址为1230，偏移地址为00C8，按公式计算，段地址1230*16=12300，12300+00C8=123C8,则123C8就是物理地址。<br />一个N进制的数据乘以N，相当于该数据左移1位。例：一个十进制的数据乘以十，相当于该数据左移一位。<br />段地址*16 + 偏移地址 = 物理地址的本质就是&#160; 基础地址 + 偏移地址 = 物理地址<br />之所以采用这个办法，是因为8086CPU为16位结构，无法一次性传输处理20位数据。换个不太准确的说法，就好比一辆汽车，他要从A到B，但汽油不够，只能先跑一段路，再加一次油跑到B点。<br />8086也是如此，无法一次给出20位物理地址，便先给出16位的段地址，将其乘以16之后变成20位的基础地址，然后再给出一个偏移地址，最后相加得到物理地址。<br />内存并不分段，段的划分来自于CPU，是人类假想出来便于管理内存的一个概念。<br />在编程时，可以根据需要将若干地址连续的内存单元看做一个段。<br />如：10000H——100FFH这个内存地址区间，既可以看做是10000H——100FFH一个段，也可以看做是10000H——1007FH，10080H——100FFH这2个段。<br />10000H——100FFH这个段，起始地址（基础地质）为10000H，段地址为1000H，大小为100H。<br />大小的计算方法，100FFH - 10000H = FFH，这个结果即是大小，转换成十进制就是255。由于计算机从0开始编号，所以0——255，有256个数。将256转换成16进制，结果就是100H。<br />用段地址*16来定位段的起始地址（基础地质），所以一个段的起始地址一定是16的倍数。<br />用偏移地址来定位段中的内存单元，而偏移地址为16位，16位的寻址能力为64KB，所以一个段的长度最大为64KB。<br />CPU可以用不同的段地址和偏移地址来形成同一个物理地址。<br />检测点2.2<br />给定段地址位0001H，仅通过变化偏移地址寻址，CPU的寻址范围是00010H到1000FH。<br />有一段数据存放在20000H内存单元中，现给定段地址为SA，若想用偏移地址寻到此单元，则SA应满足的条件是：最小为<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 最大为2000H<br />这道题很纳闷，偏移地址的变化范围是0H——FFFFH，最大好理解，段地址最大偏移地址就最小，根据SA*16 + 偏移地址 = 20000H来计算，SA最大应该是2000H，但SA最小偏移地址最大时，SA*16 + FFFFH = 20000H，算到的SA*16=10001H，这个东西要怎么写，高手求解，谷歌了老半天了不得其解啊。<br />当段地址给定为SA&lt;=1000H,或SA&gt;=2000H时，CPU无论怎么变化偏移地址都无法寻到20000H这个单元。<br />2012年8月19日5:26:55&#160; &#160; 晚上脑子不好使，把问题单独发一下，明天早上再去百度看看。好纠结。</p><p>物理地址＝SA*16+EA&#160; <br />EA的变化范围为0h~ffffh&#160; <br />物理地址范围为(SA*16+0h)~(SA*16+ffffh)&#160; <br />现在SA=0001h,那么寻址范围为&#160; <br />(0001h*16+0h)~(0001h*16+ffffh)&#160; <br />=0010h~1000fh&#160; </p><p>物理地址＝SA*16+EA&#160; <br />20000h＝SA*16+EA&#160; <br />SA=(20000h-EA)/16=2000h-EA/16&#160; <br />EA取最大值时,SA=2000h-ffffh/16=1001h,SA为最小值&#160; <br />EA取最小值时,SA=2000h-0h/16=2000h,SA为最大值<br />找到答案居然兴奋的睡不着了。。。。。。。。。。。2012年8月19日5:46:53<br />突然间发现自己刚才走了岔路，题目求的是SA的最大最小值而不是EA的，我在算到1001H的时候居然鬼使神差的去和EA的最大值相加，1001H*16+FFFFH=.........<br />2012年8月19日5:55:32。。。。。。。。。。。。。。明天熬夜要带咖啡，不然脑子不清晰</p>]]></description>
			<author><![CDATA[dummy@example.com (batsom)]]></author>
			<pubDate>Thu, 18 Aug 2022 12:50:47 +0000</pubDate>
			<guid>https://www.gentoo-zh.org/viewtopic.php?pid=115#p115</guid>
		</item>
	</channel>
</rss>
