百成 發表於 2020-12-23 02:35:00

汇编语言

<h2 id="汇编语言">汇编语言</h2>
<p>什么是汇编语言?</p>
<p>一般的机器语言复杂,通过简单的助记符简化了机器语言</p>
<pre><code class="language-shell">-编译器-&gt;
加 INC0100 0000
减 DEC0100 1000
乘 MUL0100 1000 0100 1000
除 DIV0100 1000 1100 1000
</code></pre>
<p>程序的本质 :</p>
<p><strong>隔阂!</strong>汇编一般用于底层的编写,或者单片机</p>
<p>C语言C++ 面向操作系统</p>
<pre><code class="language-shell">-编译器-&gt;
加 +0100 0000
减 -0100 1000
乘 *0100 1000 0100 1000
除 /0100 1000 1100 1000
</code></pre>
<p><strong>程序员鄙视链</strong></p>
<p><img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=778200831,716786850&amp;fm=26&amp;gp=0.jpg" alt="img" loading="lazy"></p>
<h3 id="进制">进制</h3>
<p>每一种进制都是完美的!</p>
<p>问题 :你真的理解10进制吗? 1 + 1 = 3 对吗? !如何用进制解决这个问题。</p>
<p>十进制 :0        1        2        3        4        5        6        7        8        9         1 + 1 = 2             20</p>
<p>我的十进制: 0         1        3        s        a        n        v        i        p        9                1 +1 = 3                30    可以自己随便定义 。</p>
<p><strong>加密解密</strong>: 程序员 用自己进制 写的程序 ! 进制的加密!</p>
<p>数据量大能找到规律</p>
<h3 id="进制的运算">进制的运算</h3>
<pre><code class="language-shell"># 八进制计算下面结果
2 + 3 = 5
2 * 4 = 10
4 + 5 = 11
4 * 5 = 24 (数 4 个 5)

# 运算的本质就是查数
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27
   
#八进制计算下面的结果九九乘法表 = 加发表!进位 计算表
277 + 333 =
277 * 54 =
237 - 54 =
234 / 4=
</code></pre>
<p><strong>八进制乘法表</strong>:</p>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023151173-1819823907.png" alt="" loading="lazy"></p>
<p><strong>八进制的加法表</strong>:<br>
<img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023156828-2144316501.png" alt="" loading="lazy"></p>
<pre><code class="language-shell">277
333 +
-----
632

277
54   *
----
1374
1673   +
------
20324
# 减法的本质就是加法   向上加法
277
54-
-----
223
# 除法
275
3/
----
77
</code></pre>
<h3 id="二进制">二进制</h3>
<p>计算机 只有 0 1 状态!</p>
<p>物理的极限 : 摩尔定律 ! 语言的极限! 并发语言!</p>
<p>为什么有这么多语言?</p>
<p>语言在某个领域怎样做到最强!物理算力正在到达极限。本质问题。</p>
<p>硬操作已经到达极限,开始追求软操作的极限!</p>
<p><strong>量子计算机</strong>:</p>
<p>可以实现量子计算的机器。提高计算机的计算力 (计算力是 <strong>核心</strong>)</p>
<p>单位:昆比特。(量子比特!)</p>
<p>量子的两个状态 。</p>
<p>量子比特,量子叠加态,量子纠缠,量子并行原理...</p>
<p>2019年。Google研究人员展示其最新54比特量子计算机,该计算机只用200秒便可计算完毕当前世界上最大的超级计算机需1万年进行的运算。</p>
<p>2020年,6.18号量子体积64的量子计算机!!!</p>
<p>光子:正交偏振方向</p>
<p>磁场:电子的自旋方向</p>
<p>民用?</p>
<p>作用如此强大的计算机 我觉得民用的可能性不高,在电子计算机已经基本满足我们的生活需求的情况下,量子计算机像电子计算机一样普及我觉得是不可能的事情。快不一定对社会是好处!可能在某些方面,游戏等带来质的飞跃。但是不能让这种计算机随随便便进入我们的社会。社会就是要满足我们的基本需求的情况下又需要保护我们的安全。量子计算机会打破这种平衡!</p>
<p>但是是要保护普通人的已经被满足的生活需求。</p>
<p>还是最求随时代进步的推进更先进的生活需求呢?</p>
<p>社会可能被分割,在没有新的资源和土地扩展的情况下,社会根据不同的需求被分割!</p>
<p>传统计算机:集成电路! 0 1 硅晶片</p>
<pre><code class="language-java">二进制:
0 1 10 11 100 101 110 111
</code></pre>
<p>二进制这么写很麻烦!二进制能否简写!</p>
<p><strong>16进制</strong></p>
<pre><code class="language-shell">0        1        2        3        4        5        6        7        8        9        a        b        c        d        e        f
1111 1111   =   ff
</code></pre>
<p>为什么要学二进制</p>
<p>汇编入门理解的基础:寄存器, 内存, 位!底层的每一个位都是有含义的。</p>
<p>汇编高级:了解层序的深层!操作系统的内核。</p>
<h3 id="数据宽度">数据宽度</h3>
<p>计算机 : 内存! 给数据增加数据宽度。</p>
<p>bit      #</p>
<p>Byte   ####        ####</p>
<p>Word    ####        ####        ####        ####</p>
<p>Dword####        ####        ####        ####        ####        ####        ####        ####</p>
<p><strong>为什么CC++ Java 都需要定义数据的类型?</strong></p>
<p><strong>因为计算机底层需要我们这些数据定义宽度!</strong></p>
<p>位      0 1</p>
<p>字节   0--0xFF</p>
<p>字       0--0xFFFF</p>
<p>双字   0--0xFFFF FFFF</p>
<p>在计算机中,每一个数据都需要给它定义类型。给它定义宽度,在内存中的宽度。</p>
<h2 id="有符号数和无符号数">有符号数和无符号数</h2>
<p>数据都是有宽度的,每个数据代表什么意思呢?</p>
<pre><code class="language-shell">0        1        0        1        0        1        0        1
</code></pre>
<p><strong>规则</strong></p>
<p>二进制解码增加一个规则?</p>
<p>无符号数 规则</p>
<pre><code class="language-shell">1001 1010#16进制 0x9A
</code></pre>
<p>有符号数 规则</p>
<p>最高位是符号位: 1 负数0 正数</p>
<pre><code class="language-shell">1001 1010
</code></pre>
<p>如何转换?</p>
<h3 id="原码---反码-补码">原码   反码 补码</h3>
<p>要用它进行计算</p>
<p><strong>有符号编码规则</strong></p>
<p>原码:        最高位符号位,对齐它的位进行本身绝对值即可。</p>
<p>反码:</p>
<ul>
<li>正数:反码和原码相同</li>
<li>负数:符号位一定是1,其余位对原码取反</li>
</ul>
<p>补码:</p>
<ul>
<li>正数:反码和补码相同</li>
<li>负数:符号位一定是1,反码加1</li>
</ul>
<h4 id="测试">测试</h4>
<pre><code class="language-shell"># 都是8 位
# 如果是正数原码 反码 补码都是一样的
1
#原码0000 0001
#反码0000 0001
#补码0000 0001
# 负数
-1
# 原码 1000 0001
# 反码 1111 1110
# 补码 1111 1111
-7
# 原码 1000 0111
# 反码 1111 1000
# 补码 1111 1001
   
# 二进制的标准
2        10
4        100
8        1000
16        10000
</code></pre>
<p><strong>如果看到一个数字,二进制,需要判断是有符号数还是无符号数</strong></p>
<h3 id="位运算">位运算</h3>
<p>计算机可以存贮所有的数字(整数,浮点数,字符),运算!</p>
<h4 id="位运算-1">位运算</h4>
<p>2*8最高高效的计算方式?<br>
很多底层的调试器,需要通过位来判断CPU的状态。</p>
<p>**与运算(and&amp;) **</p>
<pre><code class="language-shell">1011 0001
1101 1000
--------- 与运算
1001 0000
</code></pre>
<p><strong>或运算(or |)</strong></p>
<pre><code class="language-shell">1011 0001
1101 1000
--------- 与运算
1111 1001
</code></pre>
<p><strong>异或运算(xor^)</strong></p>
<pre><code class="language-shell"># 不一样就是1
1011 0001
1101 1000
--------- 异或运算
0110 1001
</code></pre>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023231344-1147978758.png" alt="" loading="lazy"></p>
<p><strong>非运算(not ~)</strong></p>
<pre><code class="language-shell">1101 1000
---------(非运算)
0010 0111
</code></pre>
<p><strong>位运算(左移乘2,右移除2)</strong></p>
<p><strong>左移:(shl&lt;&lt;)</strong></p>
<pre><code class="language-shell">0000 0001所有二进制位全部左移若干位,高位丢弃,低位补零
0000 0010
</code></pre>
<p><strong>右移:(shr&gt;&gt;)</strong></p>
<pre><code class="language-shell">0000 0001所有二进制位全部右移若干位,低位丢弃,高位补0 or 1(符号位决定)
0000 0000

int a = -10;
printf("%d\n",a&gt;&gt;2);
</code></pre>
<h3 id="位加减乘除运算">位加减乘除运算</h3>
<p>只认识0        1</p>
<p>基本数学建立在 加减乘除。(加法)</p>
<p><strong>4+5?</strong></p>
<pre><code class="language-shell"># 计算机是怎么操作的!
0000 0100
0000 0101
--------(加法:计算机是不会直接加的)
0000 1001

#计算机的实现原理

# 第一步:异或   不考虑进位,异或就可以直接出结果
0000 0100
0000 0101
---------------
0000 0001

#第二步:与运算(判断进位!如果与运算结果为0,没有进位)
0000 0100
0000 0101
-----------(与运算)
0000 0100

#第三步,将与运算的结果,左移一位, 0000 1000 进位的结果
0000 10000

#第四步,异或!
0000 0001
0000 1000
-----------
0000 1001

#第五步确认这个结果 与运算(判断进位!如果与运算结果为0,没有进位)
0000 0001
0000 1000
------------
0000 0000

# 所以最终的结果就为上一次的或运算
</code></pre>
<p><strong>4-5?</strong></p>
<pre><code class="language-shell"># 计算机是怎么操作的!
0000 0100
1111 1011
--------(减法:计算机是不会直接减的)
1111 1111 ff -1

0000 0100
1111 1011
---------- 异或(如果不考虑进位,异或就可以直接出结果)
1111 1111

0000 0100
1111 1011
---------- 与运算(如果不考虑进位,异或就可以直接出结果)
0000 0000

最终结果为
1111 111116ff 10 -1
</code></pre>
<h2 id="汇编语言-1">汇编语言</h2>
<p>把上面一系列指令转换成汇编语言。让计算机执行</p>
<p>需要   <strong>编译器</strong></p>
<p>最古老的编译器,越靠近底层</p>
<p>在学习汇编语言之前,需要掌握环境的配置。</p>
<p>1.VC6(程序到汇编的过程</p>
<p>2.OD</p>
<p>3.抓包工具</p>
<p>4.加密解密工具</p>
<p><strong>学汇编不是为了写代码</strong></p>
<ul>
<li>理解程序的本质</li>
</ul>
<p>《汇编语言》<br>
<img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023258483-1857754003.png" alt="" loading="lazy"></p>
<p>16位汇编现在大多数 计算机是 32 位</p>
<p><strong>32位 和 64 位本质架构区别不大,主要是寻址能力增加。</strong></p>
<p>汇编入门:了解汇编和程序的对应方式,程序的本质!</p>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023316684-743720566.png" alt="" loading="lazy"></p>
<h3 id="通用寄存器">通用寄存器</h3>
<p><strong>寄存器:</strong></p>
<p>存储顺序: CPU &gt; 内存 &gt;硬盘</p>
<p>通用寄存器可以存任意的东西</p>
<pre><code class="language-shell"># 32位的通用寄存器只有8个
EAX   FFFF FFFF
ECX   FFFF FFFF
EDX   FFFF FFFF
EBX   FFFF FFFF
ESP   FFFF FFFF
EBP   FFFF FFFF
ESI   FFFF FFFF
EDI   FFFF FFFF
</code></pre>
<p><strong>计算机如何往寄存器中存值</strong></p>
<p>对于二进制来说,直接修改值</p>
<p>计算机如果像寄存器中存值</p>
<p><strong>mov指令</strong></p>
<pre><code class="language-shell">mov 存的数
mov        存的地址
</code></pre>
<h3 id="内存">内存</h3>
<p>可以将数字写入寄存器,可以将寄存器中的值写到寄存器</p>
<p>计算机 : 计算力</p>
<p><strong>不同的寄存器</strong></p>
<pre><code>32位           16位                8位

EAX                AX               AL
ECX                CX               CL
EDC                DX               DL
EBX                BX               BL

ESP                SP               AH
ENP                NP               CH
ESI                SI               DH
EDI                DI               BH
</code></pre>
<p>8位: L低八位H 高八位</p>
<p>除了通用 寄存器 其他的寄存器都有自己的特殊功能</p>
<h3 id="内存-1">内存</h3>
<p>寄存器小,不够用,数据放在内存里面!</p>
<p>每个应用程序进程都有一个 4GB 的内存空间。虚拟内存。</p>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023327571-162070967.png" alt="" loading="lazy"></p>
<p>程序运行的 时候 才会 用的 物理内存</p>
<p>1 B = 8 bit</p>
<p>1 kb = 1028B</p>
<p>1Mb = 1028KB</p>
<p>1Gb = 1024MB</p>
<p>4G= 4096 MB= 343 5973 8368 B</p>
<p><strong>内存地址</strong></p>
<p>存一个数:占用大小,数据宽度!存到哪里?</p>
<p>给每个空间起一个编号,也就是分配一个地址。</p>
<p>32位: 寻址能力 位 4GB</p>
<p>FFFF FFFF + 1 = 10000 0000最大的值</p>
<p>位怎么限制内存大小。</p>
<p>10000 0000内存地址* 8= 80000 0000</p>
<p>转换位 10进制 /8 : 42 9496 7296</p>
<p>42 9496 7296 /1024/1024/1024 = 4 GB</p>
<p>所以 64 位 绰绰有余</p>
<p>每个内存地址 都有一个 编号 ! 通过这些编号 存值</p>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023334716-191741507.png" alt="" loading="lazy"></p>
<p><strong>内存如何存值?</strong></p>
<ul>
<li>数据宽度: byte word dword</li>
<li>地址的位置:0xFFFFFFFF</li>
<li>不是任意的地址 ,都可以写入, 需要申请过的内存 ,才可以使用</li>
</ul>
<pre><code class="language-shell">汇编如何向内存中写值
mov 数据宽度 内存地址 .值
mov byte/word/dword/qword
mov byte ptr ds:,1
传递的值的大小一定要和数据宽度相等。
</code></pre>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023345500-486127512.png" alt="" loading="lazy"></p>
<p><img src="https://img2020.cnblogs.com/blog/2251105/202012/2251105-20201223023416631-256252572.png" alt="" loading="lazy"></p>
<p><strong>内存地址写法很多</strong></p>
<ul>
<li>ds:内存地址偏移</li>
<li>ds:加寄存器</li>
<li>ds:加寄存器 偏移</li>
</ul>
<p>数组[]</p>
<p>ds:</p>
<p>ds:</p><br><br>
来源:https://www.cnblogs.com/AronJudge/p/14176511.html
頁: [1]
查看完整版本: 汇编语言