Loading... <!-- wp:audio {"id":181} --> <figure class="wp-block-audio"><audio controls src="https://www.cjovi.icu/usr/uploads/2020/10/10-November-Rain.m4a"></audio><figcaption><em><span class="has-inline-color has-luminous-vivid-amber-color"><span class="external-link"><a class="no-external-link" href="https://music.163.com/#/song?id=18094919" target="_blank"><i data-feather="external-link"></i>November Rain</a></span></span></em></figcaption></figure> <!-- /wp:audio --> <!-- wp:paragraph --> <p>今天看了将近三章,效率还算不错</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>第四章过的很快,没什么特别的。</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":3} --> <h3>编译链接的过程</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>再强化一次,masm.exe:编译源代码,产生目标文件(.obj),link.exe:链接目标文件,产生可执行文件(.exe)。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>注:通过<code>debug .exe</code>可以实现调试</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":3} --> <h3>程序的加载过程</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>分配一段有足够空间的内存地址,前256B为PSP区段,用以与DOS交互,之后为程序区段。两区段连续,但是段地址不一样。</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":3} --> <h3>当前未解释的问题</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>代码段末尾要添加:</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>mov ax,4c00h int 21h</code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>目的是实现程序的返回,让shell可以继续执行。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>PSP区段,用以与dos交互。</p> <!-- /wp:paragraph --> <!-- wp:separator --> <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:paragraph --> <p>第五章主要是[..]到[bx]的转变和段前缀的使用,以及最主要的loop指令。</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":3} --> <h3>[bx]和段前缀</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>首先我觉得[bx]没什么特别的,不过是[..]中的立即数变成了寄存器,8086中只有bx这一个通用寄存器可以用来寻址,[ax]这样的会报错。当然在degug中可以[立即数]这样用,而汇编程序里面<strong>[立即数]会被转成立即数本身</strong>,<span class="has-inline-color has-luminous-vivid-orange-color"><strong>达不到目的</strong></span>,需要使用cs:[立即数]才行。而[bx]则可以直接用,等价于ds:bx。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>段前缀即指<code>ds:</code>这样的显式指明段寄存器的代码。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>这里有引入了新的段寄存器<strong>ES</strong>(extra segment),这是一个额外的段寄存器,没有特殊用途,在需要的时候使用即可。</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":5} --> <h5><span class="has-inline-color has-vivid-purple-color">关于实模式的一些危险</span></h5> <!-- /wp:heading --> <!-- wp:paragraph --> <p>实模式下,cpu可以直接执行所有代码,若对存放了其他程序数据的内存进行修改,会造成系统出现问题,dos中00200h-002ffh中往往不存放数据,可以暂时使用这些。</p> <!-- /wp:paragraph --> <!-- wp:separator --> <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:heading {"level":3} --> <h3>loop</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>loop指令主要用来进行循环。</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>mov cx,10 s:inc bx ;inc指令可以使寄存器中的值自加一 loop s </code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>这段代码中,<code>loop s</code>指明了循环标识符,每一次到loop时会执行两个操作,</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>1、cx=cx-1;2、<span class="has-inline-color has-pale-pink-color">判断cx是否为零</span>,若为零则跳出循环,执行下一条语句,否则跳至标识符处</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>也就是说cx在这里扮演了for里的i的角色。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>在debug中,用指令p可以直接执行玩循环,g <em>address</em>可以直接使ip指向<em>address</em>并执行玩之前所有的指令。</p> <!-- /wp:paragraph --> <!-- wp:separator --> <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:paragraph --> <p>一个细碎的点,在汇编程序中,不能以字母作为数字的第一位,如a000h是不合法的,这时要使用0a000h。</p> <!-- /wp:paragraph --> <!-- wp:separator --> <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:paragraph --> <p><strong><span class="has-inline-color has-pale-pink-color">实验中的一个点:CX在初始化时会初始化为程序所占字节大小</span></strong></p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>至此第五章完成:)</p> <!-- /wp:paragraph --> <!-- wp:separator --> <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:heading {"level":3} --> <h3>代码段中使用数据</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>可以使用<code>dw</code>(define word)指令来向代码段中添加数据,这些数据会直接存储到内存中,遗憾的是,编译器并无法智能地改变IP的值,所以会把数据段当作指令来执行,这样肯定会出现问题,所以就有了<code>end start</code>指令</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>.... codesg segment dw 1342h,1324h,1242h start: .... ;注意 codesg ends end start ;注意!</code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>这样IP就会指向第一条指令了。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p><span class="has-inline-color has-vivid-red-color"><strong>注意这里的start并不是必须的,写成stat之类的也有一样的效果。</strong></span></p> <!-- /wp:paragraph --> <!-- wp:heading {"level":3} --> <h3>分段</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>显然,数据代码和栈混用一段是非常不明智的,不仅难以管理,使程序混乱,还会造成段空间不足的情况(8086中,一个段最大只能有64KB)</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>因此,我们可以用与代码段类似的方法,来定义栈和数据段。</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>assume cs:code,ds:data,ss:stack stack segment ;栈段 stack ends data segment ;数据段 data ends code segment ;代码段 code ends</code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>从这里我有了新的理解,即一个段的作用,只需要通过与对应的段寄存器assume就可以了,其本质是人为对段寄存器的控制。</p> <!-- /wp:paragraph --> <!-- wp:heading {"level":4} --> <h4><span class="has-inline-color has-pale-pink-color">一个反(我的)直觉的部分</span></h4> <!-- /wp:heading --> <!-- wp:paragraph --> <p>虽然assume了ds和data,但是ds并不会指向数据段,对ss也是同理,一下的代码在debug中运行的结果证实了这一点。</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>assume cs:code,ss:stack,ds:data stack segment dw 0,0,0,0,0,0,12h stack ends data segment dw 3521h,1256h data ends code segment start: mov ax,data mov ax,stack mov ax,ss mov ax,4c00h int 21h code ends end start</code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>所以要通过</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>mov ax,data mov ds,ax</code></pre> <!-- /wp:code --> <!-- wp:paragraph --> <p>来实现</p> <!-- /wp:paragraph --> 最后修改:2021 年 01 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧