[
  {
    "path": "README.md",
    "content": "# 汇编语言学习\n<b>参考书：</b>使用王爽写的《汇编语言》第三版<br />\n<b>学习工具(win7 x64)：</b>\nDOSBox 0.74、masm.exe、link.exe、debug.exe。<br />\n另外需要一款编辑器，用来编辑源程序，推荐sublime text。需要到这里下载支持汇编语法高亮的插件：<a href=\"https://github.com/Nessphoro/sublimeassembly\" target=\"_blank\">https://github.com/Nessphoro/sublimeassembly</a><br />\n## 目录介绍\n<big><b>学习工具</b></big>：包含win7 64位下需要的工具：DOSBox 0.74安装包、masm.exe、link.exe、debug.exe<br />\n<big><b>experiment.asm</b></big>：参考书上面的练习与实验（不全，但需要的代码都在里面）\n\n## 64位windows7下DOSBox使用方法：\n<big><b>step1：</b></big>新建文件夹（下面以`C:\\coding\\assembly-language-learning`为例）<br />\n<big><b>step2：</b></big>将`debug.exe`、`masm.exe`、`link.exe`放到`C:\\coding\\assembly-language-learning`文件夹下<br />\n<big><b>step3：</b></big>打开DOSBox。这里可以看到Z:\\DOSBox里的虚拟盘，我们采用mount命令将其转变到`C:\\coding\\assembly-language-learning`目录下，如果只是用这一次，可以直接在命令行中输入如下命令：\n<pre><code>Z:\\> mount d C:\\coding\\assembly-language-learning\nZ:\\> D:\nD:\\>\n</code></pre>\n如果是一直使用，则可以修改autoexe，方法如下：\n打开`DOSBox 0.74 Options`，在打开的文件里找到`[autoexec]`（应该在文本的最后位置），向下面那样在末尾添加上面两条命令\n<pre><code>[autoexec]\n\\# Lines in this section will be run at startup.\n\\# You can put your MOUNT lines here.\nmount d c:\\coding\\assembly-language-learning\nD:\n</code></pre>\n<big><b>step4：</b></big>接下来在目录C:\\coding\\assembly-language-learning下编写源程序（假设1.asm）并按照如下方式编译链接并运行或者调试\n<pre><code>[autoexec]\nD:\\>masm 1;\t\t快速编译（省略生成中间文件）\nD:\\>link 1;\t\t快速链接（省略生成中间文件）\nD:\\>1.exe\t\t运行可执行程序\nD:\\>debug 1.exe\t\tdebug中进行调试\n</code></pre>"
  },
  {
    "path": "experiments.asm",
    "content": ";=======================================================\n\n; ;17.3 字符串的输入\n; assume cs:code\n\n; data segment\n; \tdb 128 dup (0)\n; data ends\n\n; code segment\n; start:\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov si, 0\n\n; \tmov dh, 12\n; \tmov dl, 39\n\n; \tcall getstr\n\n; \tmov ax, 4c00h\n; \tint 21h\n; ;-----------接受字符串输入------------------------------\n; getstr:\tpush ax\n\t\n; getstrs:\tmov ah, 0\n; \tint 16h\n; \tcmp al, 20h\n; \tjb nochar\n; \tmov ah, 0\n; \tcall charstack\n; \tmov ah, 2\n; \tcall charstack\n; \tjmp getstrs\n\n; nochar:\tcmp ah, 0eh\n; \tje backspace\n; \tcmp ah, 1ch\n; \tje return\n; \tjmp getstrs\n\n; backspace:\tmov ah, 1\n; \tcall charstack\n; \tmov ah, 2\n; \tcall charstack\n; \tjmp getstrs\n\n; return:\tmov al, 0\n; \tmov ah, 0\n; \tcall charstack\n; \tmov ah, 2\n; \tcall charstack\n\n; \tpop ax\n; \tret\n; ;-----------子程序：字符串入栈，出现，显示--------------\n; charstack:\tjmp short charstart\n\n; table\tdw charpush, charpop, charshow\n; top\tdw, 0\n\n; charstart:\tpush ax\n; \tpush bx\n; \tpush dx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; \tcmp ah, 2\n; \tja sret\n; \tmov bl, ah\n; \tmov bh, 0\n; \tadd bx, bx\n; \tjmp word ptr table[bx]\n\n; charpush:\tmov bx, top\n; \tmov [si][bx], al\n; \tinc top\n; \tjmp sret\n\n; charpop:\tcmp top, 0\n; \tje sret\n; \tdec top\n; \tmov bx, top\n; \tmov al, [si][bx]\n; \tjmp sret\n\n; charshow:\tmov bx, 0B800h\n; \tmov es, bx\n; \tmov al, 160\n; \tmov ah, 0\n; \tmul dh\n; \tmov di, ax\n; \tadd dl, dl\n; \tmov dh, 0\n; \tadd di, dx\n\n; \tmov bx, 0\n\n; charshows:\tcmp bx, top\n; \tjne noempty\n; \tmov byte ptr es:[di], ' '\n; \tjmp sret\n\n; noempty:\tmov al, [si][bx]\n; \tmov es:[di], al\n; \tmov byte ptr es:[di+2], ' '\n; \tinc bx\n; \tadd di, 2\n; \tjmp charshows\n\n; sret:\tpop di\n; \tpop si\n; \tpop es\n; \tpop ds\n; \tpop dx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;=======================================================\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n\n\n; ;17.2 接收用户的键盘输入...\n; assume cs:code\n\n; code segment\n\n; start:\tmov ah, 0\n; \tint 16h\n\n; \tmov ah, 1\n; \tcmp al, 'r'\n; \tje red\n; \tcmp al, 'g'\n; \tje green\n; \tcmp al, 'b'\n; \tje blue\n\n; \tjmp short sret\n\n; red:\tshl ah, 1\n; green:\tshl ah, 1\n; blue:\tmov bx, 0B800h\n; \tmov es, bx\n; \tmov bx, 1\n; \tmov cx, 2000\n; s:\tand byte ptr es:[bx], 11111000B\n; \tor es:[bx], ah\n; \tadd bx, 2\n; \tloop s\n; \tjmp short start\n\n; sret:\tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n; ;实验16 编写包含多个功能子程序的中断例程\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n; start:\tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\t\t;初始化栈\n\n; ;-----------新int 7ch安装程序---------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset setscreen \t;ds:[si] 源\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t\t;es:[di] 目的\n\n; \tmov cx, offset setscreenend - offset setscreen\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------中断向量设置程序----------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n\t\n; \tmov ah, 3\n; \tint 7ch\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------int 7ch 源程序-----------------------------------\n; \tORG 200h\t\t;伪指令，表示下一条指令从偏移地址200h开始\n; \t\t\t;正好和安装后的偏移地址相同\n; \t\t\t;如果没有ORG 200h，此中断例程被安装之后，标号所代表的地址变了\n; \t\t\t;和之前编译器编译的有区别\n; setscreen:\tjmp short set\n\n; table\tdw sub1, sub2, sub3, sub4\n\n; set:\tpush ax\n; \tpush bx\n\n; \tcmp ah, 3\n; \tja setret\n; \tmov bl, ah\n; \tmov bh, 0\n; \tadd bx, bx\t\t;根据ah中的功能号计算对应子程序在table表中的地址\n\n; \tcall word ptr table[bx]\t;调用对应的子程序\n\n; setret:\tpop bx\n; \tpop ax\n\n; \tiret\n; ;-----------sub-----------------------------------------\n; sub1:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 0\n; \tmov cx, 2000\n\n; sub1s:\tmov byte ptr es:[bx], ' '\n; \tadd bx, 2\n; \tloop sub1s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub2:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 1\n\n; \tmov cx, 2000\n; sub2s:\tand byte ptr es:[bx], 11111000B\n; \tor es:[bx], al\n; \tadd bx, 2\n; \tloop sub2s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub3:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 1\n\n; \tmov cl, 4\n; \tshl al, cl\n\n; \tmov cx, 2000\n; sub3s:\tand byte ptr es:[bx], 10001111B\n; \tor es:[bx], al\n; \tadd bx, 2\n; \tloop sub3s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub4:\tpush bx\n; \tpush cx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; \tmov bx, 0b800h\n; \tmov ds, bx\n; \tmov si, 160\t\t;ds:[si] 源\n; \tmov es, bx\n; \tmov di, 0\t\t;ds:[si] 目的\n; \tcld\n\n; \tmov cx, 24\n; sub4s:\tpush cx\n; \tmov cx, 160\n; \trep movsb\n; \tpop cx\n; \tloop sub4s\n\n; \tmov cx, 80\n; \tmov si, 0\n; sub4s1:\tmov byte ptr [160*24+si], ' '\n; \tadd si, 2\n; \tloop sub4s1\n\n; \tpop di\n; \tpop si\n; \tpop es\n; \tpop ds\n; \tpop cx\n; \tpop bx\n; \tret\n\n; setscreenend:\n; \tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n; ;16.4 实现一个子程序setscreen\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n; start:\tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\t\t;初始化栈\n\n; \tmov ah, 0\n; \tcall setscreen\n; \tcall delay \t\t;清屏\n\n; \tmov ah, 1\n; \tmov al, 2\n; \tcall setscreen\n; \tcall delay \t\t;设置前景色\n\n; \tmov ah, 2\n; \tmov al, 2\n; \tcall setscreen\n; \tcall delay \t\t;设置后景色\n\n; \tmov ah, 3\n; \tcall setscreen\n; \tcall delay \t\t;向上滚动一行\n\t\n; \tmov ax, 4c00h\n; \tint 21h\n; ;-----------delay源程序---------------------------------\n; delay:\tpush ax\n; \tpush dx\n\n; \tmov dx, 5\n; \tmov ax, 0\n; circulate:\tsub ax, 1\n; \tsbb dx, 0\n; \tcmp ax, 0\n; \tjne circulate\n; \tcmp dx, 0\n; \tjne circulate\n\n; \tpop dx\n; \tpop ax\n; \tret\n; ;=======================================================\n; ;-----------setscreen-----------------------------------\n; setscreen:\tjmp short set\n\n; table\tdw sub1, sub2, sub3, sub4\n\n; set:\tpush ax\n; \tpush bx\n\n; \tcmp ah, 3\n; \tja setret\n; \tmov bl, ah\n; \tmov bh, 0\n; \tadd bx, bx\t\t;根据ah中的功能号计算对应子程序在table表中的地址\n\n; \tcall word ptr table[bx]\t;调用对应的子程序\n\n; setret:\tpop bx\n; \tpop ax\n; \tret\n; ;-----------sub-----------------------------------------\n; sub1:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 0\n; \tmov cx, 2000\n\n; sub1s:\tmov byte ptr es:[bx], ' '\n; \tadd bx, 2\n; \tloop sub1s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub2:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 1\n\n; \tmov cx, 2000\n; sub2s:\tand byte ptr es:[bx], 11111000B\n; \tor es:[bx], al\n; \tadd bx, 2\n; \tloop sub2s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub3:\tpush bx\n; \tpush cx\n; \tpush es\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 1\n\n; \tmov cl, 4\n; \tshl al, cl\n\n; \tmov cx, 2000\n; sub3s:\tand byte ptr es:[bx], 10001111B\n; \tor es:[bx], al\n; \tadd bx, 2\n; \tloop sub3s\n\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tret\n\n\n; sub4:\tpush bx\n; \tpush cx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; \tmov bx, 0b800h\n; \tmov ds, bx\n; \tmov si, 160\t\t;ds:[si] 源\n; \tmov es, bx\n; \tmov di, 0\t\t;ds:[si] 目的\n; \tcld\n\n; \tmov cx, 24\n; sub4s:\tpush cx\n; \tmov cx, 160\n; \trep movsb\n; \tpop cx\n; \tloop sub4s\n\n; \tmov cx, 80\n; \tmov si, 0\n; sub4s1:\tmov byte ptr [160*24+si], ' '\n; \tadd si, 2\n; \tloop sub4s1\n\n; \tpop di\n; \tpop si\n; \tpop es\n; \tpop ds\n; \tpop cx\n; \tpop bx\n; \tret\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n; ;16.3 直接定址表\n; ;编写子程序，计算sin(x)...\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n\n; start:\tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tmov ax, 60\n; \tcall showsin\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------showsin源程序-------------------------------\n; showsin:\tjmp short show\n\t\n; table \tdw ag0, ag30, ag60, ag90, ag120, ag150, ag180\n; ag0\tdb '0', 0\n; ag30\tdb '0.5', 0\n; ag60\tdb '0.866', 0\n; ag90\tdb '1', 0\n; ag120\tdb '0.866', 0\n; ag150\tdb '0.5', 0\n; ag180\tdb '0', 0\n\n; show:\tpush ax\n; \tpush bx\n; \tpush cx\n; \tpush es\n; \tpush di\n\n; \tmov ah, 0\n; \tmov bl, 30\n; \tdiv bl\n; \tmov bl, al\n; \tmov bh, 0\n; \tadd bx, bx\n; \tmov bx, table[bx]\n\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 160*12 + 39*2\n\n; shows:\tmov ah, cs:[bx]\n; \tcmp ah, 0\n; \tje showret\n; \tmov es:[di], ah\n; \tadd di, 2\n; \tinc bx\n; \tjmp short shows\n\n; showret:\tpop di\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n\n; ;16.3 直接定址表\n; ;编写子程序，以十六进制的形式在屏幕中间显示给定的字节型数据\n; assume cs:code\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n; code segment\n\n; start:\tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tmov al, 11000001B\n; \tcall showbyte\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------shorbyte源程序------------------------------\n; showbyte:\tjmp short show\n; \ttable db '0123456789ABCDE'\n\n; show:\tpush ax\n; \tpush bx\n; \tpush cx\n; \tpush es\n; \tpush di\n\n; \tmov ah, al\n; \tmov cl, 4\n; \tshr ah, cl\n; \tand al, 00001111B\t;ah al分别保存两个数字\n\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov di, 160*12 + 39*2\t;从es:[di]开始输出\n\n; \tmov bl, ah\n; \tmov bh, 0\n; \tmov ah, table[bx]\t;将ah数字转换为表示其的ascii码\n; \tmov es:[di], ah\t;显示\n\n; \tmov bl, al\n; \tmov bh, 0\n; \tmov al, table[bx]\t;将al数字转换为表示其的ascii码\n; \tmov es:[di+2], al\t;显示\n\n; \tpop di\n; \tpop es\n; \tpop cx\n; \tpop bx\n; \tpop ax\n\n; \tret\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n; ;实验15 安装新的int 9中断例程\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n; start:\n; \tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\t\t;初始化栈\n\n; ;-----------新int 9安装程序-----------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 204h\t;es:[di] 新的int 9中断例程安装地址\n\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset int9\t;ds:[si] int 9中断例程所在内存首地址\n\n; \tmov cx, offset int9end - offset int9\n; \tcld\n; \trep movsb\n; ;-----------设置中断向量--------------------------------\n; \tpush es:[9*4]\n; \tpop es:[200h]\n; \tpush es:[9*4 + 2]\n; \tpop es:[202h]\t;将原int 9中断例程入口地址保存在0:200单元处\n\n; \tcli\n; \tmov word ptr es:[9*4], 204h\n; \tmov word ptr es:[9*4+2], 0\n; \tsti\n; ;=======================================================\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------新int 9源程序-------------------------------\n; int9:\tpush ax\n; \tpush bx\n; \tpush cx\n; \tpush es\n\n; \tin al, 60h\n\n; \tmov bx, 0\n; \tmov es, bx\n\n; \tpushf\n; \tpushf\n; \tpop bx\n; \tand bh, 11111100B\n; \tpush bx\n; \tpopf\n; \tcall dword ptr es:[200h];对int指令进行模拟，调用原来的int9中断指令\n\n; \tcmp al, 9eh\n; \tjne int9ret \t;如果不是F1，则直接返回\n\t\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 0\n; \tmov cx, 2000\n; s:\tmov byte ptr es:[bx], 'A'\n; \tadd bx, 2\n; \tloop s \t;如果是F1，改变显示的颜色\n\n; int9ret:\tpop es\n; \tpop cx\n; \tpop bx\n; \tpop ax\n; \tiret\n; int9end:\tnop\n\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n\n\n; ;15.5 安装新的int 9中断例程\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n; start:\n; \tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\t\t;初始化栈\n\n; ;-----------新int 9安装程序-----------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 204h\t;es:[di] 新的int 9中断例程安装地址\n\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset int9\t;ds:[si] int 9中断例程所在内存首地址\n\n; \tmov cx, offset int9end - offset int9\n; \tcld\n; \trep movsb\n; ;-----------设置中断向量--------------------------------\n; \tpush es:[9*4]\n; \tpop es:[200h]\n; \tpush es:[9*4 + 2]\n; \tpop es:[202h]\t;将原int 9中断例程入口地址保存在0:200单元处\n\n; \tcli\n; \tmov word ptr es:[9*4], 204h\n; \tmov word ptr es:[9*4+2], 0\n; \tsti\n; ;=======================================================\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------新int 9源程序-------------------------------\n; int9:\tpush ax\n; \tpush bx\n; \tpush cx\n; \tpush es\n\n; \tin al, 60h\n\n; \tmov bx, 0\n; \tmov es, bx\n\n; \tpushf\n; \tpushf\n; \tpop bx\n; \tand bh, 11111100B\n; \tpush bx\n; \tpopf\n; \tcall dword ptr es:[200h];对int指令进行模拟，调用原来的int9中断指令\n\n; \tcmp al, 3bh\n; \tjne int9ret \t;如果不是F1，则直接返回\n\t\n; \tmov bx, 0b800h\n; \tmov es, bx\n; \tmov bx, 1\n; \tmov cx, 2000\n; s:\tinc byte ptr es:[bx]\n; \tadd bx, 2\n; \tloop s \t;如果是F1，改变显示的颜色\n\n; int9ret:\tpop es\n; \tpop cx\n; \tpop bx\n; \tpop ax\n; \tiret\n; int9end:\tnop\n\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n\n\n; ;15.4 编写int 9中断例程\n; assume cs:code\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; data segment\n; \tdw 0, 0\n; data ends\n\n; code segment\n; start:\n; \tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\t\t;初始化栈\n\n; \tmov ax, data\n; \tmov ds, ax\t\t;初始化ds指向data段\n\n; \tmov ax, 0\n; \tmov es, ax\t\t;初始化es指向中断向量表所在的0段\n\n; \tcli\n; \tpush es:[9*4]\n; \tpop ds:[0]\n; \tpush es:[9*4+2]\n; \tpop ds:[2]\t\t;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中\n; \tsti\n\n; \tmov word ptr es:[9*4], offset int9\n; \tmov es:[9*4+2], cs\n\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 12*160 + 39*2\t;字符显示的位置\n; \tmov byte ptr es:[di+1], 00000010B\n; \tmov ah, 'a'\n; display:\tmov es:[di], ah\n; \tcall delay \t\t;调用延迟函数\n; \tinc ah\n; \tcmp ah, 'z'\n; \tjna display\n\n; \t;回复原来的int 9中断\n; \tcli\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov ax, data\n; \tmov ds, ax\n; \tpush ds:[0]\n; \tpop es:[9*4]\n; \tpush ds:[2]\n; \tpop es:[9*4+2]\n; \tsti\n\n; \tmov ax, 4c00h\n; \tint 21h\n; ;-----------新int9源程序--------------------------------\n; int9:\tpush ax\n; \tpush bx\n; \tpush es\n\n; \tin al, 60h\n; \t;模拟int9指令调用原来的int 9\n; \tpushf \t\t;标志寄存器入栈\n; \tpushf\n; \tpop bx\n; \tand bh, 11111100B\n; \tpush bx\n; \tpopf \t\t;设置IF=0，TF=0\n; \tcall dword ptr ds:[0]\t;调用原来的int 9中断例程\n\n; \tcmp al, 1\n; \tjne int9ret\n\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tinc byte ptr es:[di+1]\n\n; int9ret:\tpop es\n; \tpop bx\n; \tpop ax\n; \tiret\n; ;=======================================================\n; ;-----------delay源程序---------------------------------\n; delay:\tpush ax\n; \tpush dx\n\n; \tmov dx, 5\n; \tmov ax, 0\n; circulate:\tsub ax, 1\n; \tsbb dx, 0\n; \tcmp ax, 0\n; \tjne circulate\n; \tcmp dx, 0\n; \tjne circulate\n\n; \tpop dx\n; \tpop ax\n; \tret\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n; ;实验14 访问CMOS RAM\n; assume cs:code\n\n; data segment\n; \tdb 'yy/mm/dd hh:mm:ss', '$'\n; data ends\n\n; stack segment\n; \tdb 128 dup (0)\n; stack ends\n\n; code segment\n; start:\n; \tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tmov ax, data\n; \tmov ds, ax\n\t\n\n; \t;显示年月日\n; \tmov si, 0\n; \tmov cx, 3\n; \tmov al, 9\n; ymd:\tpush cx\n; \tpush ax\n; \tout 70h, al\n; \tin al, 71h\n\n; \tmov ah, al\n; \tmov cl, 4\n; \tshr ah, cl\n; \tand al, 00001111B\n\n; \tadd ah, 30h\n; \tadd al, 30h\n\n; \tmov ds:[si], ah\n; \tmov ds:[si+1], al\n; \tadd si, 3\n; \tpop ax\n; \tdec al\n; \tpop cx\n; \tloop ymd\n\n; \t;显示时分秒\n; \tmov si, 9\n; \tmov cx, 3\n; \tmov al, 4\n; hms:\tpush cx\n; \tpush ax\n; \tout 70h, al\n; \tin al, 71h\n\n; \tmov ah, al\n; \tmov cl, 4\n; \tshr ah, cl\n; \tand al, 00001111B\n; \tadd ah, 30h\n; \tadd al, 30h\n\n; \tmov ds:[si], ah\n; \tmov ds:[si+1], al\n; \tadd si, 3\n; \tpop ax\n; \tsub al, 2\n; \tpop cx\n; \tloop hms\n\n; \tmov dx, 0\n; \t;ds:[dx]指向字符串\n; \tmov ah, 9\n; \tint 21h\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n; ;检测点14.2\n; assume cs:code\n\n; code segment\n; start:\n; \tmov ax, 1\n; \tshl ax, 1\n; \tmov bx, ax\n; \tmov cl, 2\n; \tshl ax, cl\n; \tadd ax, bx\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n; ;检测点14.1(2)\n; assume cs:code\n\n; code segment\n; start:\n; \tmov al, 2\n; \tout 70h, al\n; \tmov al, 0\n; \tout 7ch, al\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n; ;检测点14.1(1)\n; assume cs:code\n\n; code segment\n; start:\n; \tmov al, 2\n; \tout 70h, al\n; \tin al, 71h\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n\n\n\n; ;实验13 编写、应用中断例程(3)\n; assume cs:code\n\n; code segment\n; s1:\tdb 'Good, better, best,', '$'\n; s2:\tdb 'Never let it rest,', '$'\n; s3:\tdb 'Till good is better,', '$'\n; s4:\tdb 'And better, best.', '$'\n; s:\tdw offset s1, offset s2, offset s3, offset s4\n; row:\tdb 2, 4, 6, 8\n\n; start:\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov bx, offset s\n; \tmov si, offset row\n\n; \tmov cx, 4\n; ok:\tmov bh, 0\n; \tmov dh, ds:[si]\n; \tmov dl, 0\n; \tmov ah, 2\n; \tint 10h\t;置光标\n\n; \tmov dx, ds:[bx]\n; \tmov ah, 9\n; \tint 21h\n\n; \tadd bx, 2\n; \tinc si\n\n; \tloop ok\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n\n; ;实验13 编写、应用中断例程(2)\n; assume cs:code\n\n; code segment\n; start:\n; ;-----------lp安装程序----------------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset lp\t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[si] 目的地址\n\n; \tmov cx, offset lpend - offset lp\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量--------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 160 * 12\t;es:[di] 开始显示\n\n; \tmov bx, offset s - offset se\n\n; \tmov cx, 80\n; s:\tmov byte ptr es:[di], '!'\n; \tadd di, 2\n; \tint 7ch\n\n; se:\tnop\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------lp源程序------------------------------------\n; lp:\n; \tpush bp\n; \tmov bp, sp\n; \tdec cx\n; \tjcxz ok\n; \tadd ss:[bp+2], bx\n\n; ok:\tpop bp\n; \tiret\n\n; lpend:\tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n; ;实验13 编写、应用中断例程(1)\n; assume cs:code\n\n; data segment\n; \tdb \"welcome to masm!\", 0\n; data ends\n\n; code segment\n; start:\n; ;-----------display安装程序-----------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset display \t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[si] 目的地址\n\n; \tmov cx, offset displayend - offset display\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量--------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n\t\n; \tmov dh, 10\n; \tmov dl, 10\n; \tmov cl, 2\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov si, 0\n; \tint 7ch\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------display源程序-------------------------------\n; display:\t\n; \tmov ax, 0b800h\n; \tmov es, ax\n\n; \tmov al, 160\n; \tmul dh\n; \tmov di, ax\n; \tmov al, 2\n; \tmul dl\n; \tadd di, ax\t\t;es:[di] 显示位置\n\n; \tmov ch, cl\n\n; dis:\tmov cl, ds:[si]\n; \tcmp cl, 0\n; \tje ok\n; \tmov es:[di], cx\n; \tadd di, 2\n; \tinc si\n; \tjmp dis\n; ok:\tiret\n\n; displayend:\tnop\n; ;=======================================================\n\n; code ends\n\n; end start\n\n\n\n; ;13.7 DOS中断例程应用\n; assume cs:code\n\n; data segment\n; \tdb 'Welcome to masm!', '$'\n; data ends\n\n; code segment\n; start:\n; \tmov ah, 2\n; \tmov bh, 0\n; \tmov dh, 5\n; \tmov dl, 12\n; \tint 10h\n\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov dx, 0\n; \tmov ah, 9\n; \tint 21h\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n; ;13.6 BIOS中断例程应用\n; assume cs:code\n\n; code segment\n; start:\n; \tmov ah, 2\t;置光标\n; \tmov bh, 0\t;第 0 页\n; \tmov dh, 5\t;第 5 行\n; \tmov dl, 12\t;第 12 列\n; \tint 10h\t;对应的中断例程\n\n; \tmov ah, 9\t;在光标显示字符\n; \tmov al, 'a'\t;字符\n; \tmov bh, 0\t;第 0 页\n; \tmov bl, 01001010b\t;颜色属性\n; \tmov cx, 80\t;字符重复个数\n; \tint 10h\t;对应的中断例程\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n\n\n; ;捡测点13.1 (2)\n; assume cs:code\n\n; data segment\n; \tdb 'conversation', 0\n; data ends\n\n; code segment\n; ;-----------jump安装程序--------------------------------\n; start:\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset jump \t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[si] 目的地址\n\n; \tmov cx, offset jumpend - offset jump\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量--------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov si, 0\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 12*160 + 3 * 2\n\t\n; \tmov bx, offset display - offset displayend\n; display:\t\n; \tcmp byte ptr [si], 0\n; \tje displayend\n; \tmov ah, 10000010B\n; \tmov al, [si]\n; \tmov es:[di], ax\n; \tinc si\n; \tadd di, 2\n; \tint 7ch\n\n; displayend:\t\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------jump源程序----------------------------------\n; jump:\tpush bp\n; \tmov bp, sp\n; \tadd [bp+2], bx\n; \tpop bp\n; \tiret\n; jumpend:\tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n; ;13.3 用7ch中断例程完成loop指令的功能\n; assume cs:code\n\n; code segment\n; start:\n; ;-----------lp安装程序----------------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset lp\t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[di] 目的地址\n\n; \tmov cx, offset lpend - offset lp\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量表------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n; \tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 160 * 12\t;es:[di]开始显示的位置\n\n; \tmov bx, offset display - offset displayend\n; \tmov cx, 80\n; display:\tmov byte ptr es:[di], '!'\n; \tadd di, 2\n; \tint 7ch\n\n; displayend:\tnop\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------lp源程序------------------------------------\n; lp:\tpush bp\n; \tmov bp, sp\n; \tdec cx\n; \tjcxz lpiret\n; \tadd [bp+2], bx\n; \t;add [sp+2], bx ;error:must be index or base register\n\n; lpiret:\tpop bp\n; \tiret\n\n; lpend:\tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n; ; 13.2 问题二\n; assume cs:code\n\n; data segment\n; \tdb 'conversation', 0\n; data ends\n\n; code segment\n; start:\n; ;-----------capital安装程序-----------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset capital \t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[di] 目的地址\n\t\n; \tmov cx, offset capitalend - offset capital\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量表------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n\n; ;=======================================================\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov si, 0\n; \tint 7ch\n; \tmov ax, 4c00h\n; \tint 21h\n; ;-----------capital程序源代码---------------------------\n; capital:\tpush cx\n; \tpush si\n\n; change:\tmov ch, 0\n; \tmov cl, ds:[si]\n; \tjcxz capitalret\n; \tand cl, 11011111B\n; \tmov ds:[si], cl\n; \tinc si\n; \tjmp change\n\n; capitalret:\tpop si\n; \tpop cx\n; \tiret\n\n; capitalend:\tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n; 13.2 问题一\n; assume cs:code\n\n; code segment\n; start:\n; ;-----------sqr安装程序---------------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset sqr \t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[di] 目的地址\n\n; \tmov cx, offset sqrend - offset sqr\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量表------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[7ch*4], 200h\n; \tmov word ptr es:[7ch*4+2], 0\n; ;=======================================================\n; \tmov ax, 3456\n; \tint 7ch\n; \tadd ax, ax\n; \tadc dx, dx\n\n; \tmov ax, 4c00h\n; \tint 21h\n; ;-----------sqr程序源代码-------------------------------\n; sqr:\tmul ax\n; \tiret\n; sqrend:\n; \tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n; ;实验12 编写0号中断的处理程序\n; ;重新编写一个0号中断处理程序，它的功能是在屏幕中间显示“overflow!”\n; ;然后返回到操作系统\n; assume cs:code\n\n; code segment\n; start:\n; ;-----------do0安装程序---------------------------------\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, offset do0 \t;ds:[si] 源地址\n\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov di, 200h\t;es:[di] 目的地址\n\n; \tmov cx, offset do0end - offset do0\n; \tcld\n; \trep movsb\n; ;=======================================================\n; ;-----------设置中断向量表------------------------------\n; \tmov ax, 0\n; \tmov es, ax\n; \tmov word ptr es:[0*4], 200h\n; \tmov word ptr es:[0*4 + 2], 0\n; ;=======================================================\n\t\n; \tmov ax, 1000h\n; \tmov bx, 1\n; \tdiv bh\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-----------do0程序源代码-------------------------------\n; do0:\t\n; \tjmp short do0start\n; \tdb \"overflow!\", 0\n\n; do0start:\tmov ax, 0b800h\n; \tmov es, ax\n; \tmov di, 12*160 + 35*2\t;从es:[di]开始显示\n\n; \tmov ax, cs\n; \tmov ds, ax\n; \tmov si, 202h\t;ds:[si] 显示的字符串\n\n; display:\tmov ch, 0\n; \tmov cl, ds:[si]\n; \tjcxz displayend\n; \tmov ch, 10000010B\n; \tmov es:[di], cx\n; \tinc si\n; \tadd di, 2\n; \tjmp display\n\n; displayend:\tmov ax, 4c00h\n; \tint 21h\n; do0end:\t\n; \tnop\n; ;=======================================================\n; code ends\n\n; end start\n\n\n\n\n\n\n\n\n; ;实验11-编写子程序\n; assume cs:code\n\n; data segment\n; \tdb 'Beginners All-purpose Symbolic Instruction Code.', 0\n; data ends\n\n; code segment\n; start:\n; \tmov ax, data\n; \tmov ds, ax\n; \tmov si, 0\n; \tcall letterc\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-------------------------------------------------------------------\n; letterc:;ds:[si]开始的小写字母转变为大写字母\n; \tpush cx\n\n; change:\tmov ch, 0\n; \tmov cl, ds:[si]\n; \tjcxz changeRet\n; \tcmp cl, 'a'\n; \tjb next\n; \tcmp cl, 'z'\n; \tja next\n; \tsub cl, 20h\n; \tmov ds:[si], cl\n\n; next:\tinc si\n; \tjmp change\n\n; changeRet:\tpop cx\n; \tret\n\n; code ends\n\n; end start\n\n\n\n\n; ;课程设计1\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; datasg segment\n; \tdb '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983'\n; \tdb '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992'\n; \tdb '1993', '1994', '1995'\n; \t;以上表示21年的21个字符串\n; \tdd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 87479, 140417, 197514\n; \tdd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000\n; \t;以上表示21年公司收入的21个dword型数据\n; \tdw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226\n; \tdw 11542, 14430, 15257, 17800\n; \t;以上表示21年公司雇员人数的21个word型数据\n; datasg ends\n\n; tablesg segment\n; \t          ;'0123456789ABCDEF'\n; \tdb 21 dup ('year summ ne ?? ')\n; tablesg ends\n\n; ;栈段，多层循环中保存cx\n; stacksg segment\n; \tdb 128 dup (0)\n; stacksg ends\n\n; stringsg segment\n; \tdb 10 dup ('0'), 0\n; stringsg ends\n\n; codesg segment\n; start:\t;初始化栈\n; \tmov ax, stacksg\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tcall input_table\n; \tcall clear_screen\n; \tcall output_table\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; ;-------------------------------------------------------------------\n; show_year:\t;将ds:[si]开始的四个字符的年份写入es:[di]开始的内存中\n; \t;将用到的寄存器压入栈\n; \tpush cx\n; \tpush ax\n; \tpush bx\n; \tpush bp\n; \tpush di\n\n; \tadd di, 3 * 2\t;这儿修改年份开始列\n; \tmov bx, 0\t;bx用来指示显示器内存的位置（每次加2）\n; \tmov bp, 0\t;bp用来指示原数据的位置（每次加1）\n; \tmov cx, 4\t;循环四次显示4个字符\n; showYear:\n; \tmov al, ds:[si+bp]\n; \tmov es:[di+bx], al\n; \tinc bp\n; \tadd bx, 2\n; \tloop showYear\n\t\n; \tpop di\n; \tpop bp\n; \tpop bx\n; \tpop ax\n; \tpop cx\n\n; \tret\n; ;===================================================================\n; ;-------------------------------------------------------------------\n; long_div:\t\n; \tmov cx, 10\n; \tpush ax\n; \tmov bp, sp\n\n; \tmov ax, dx\n; \tmov dx, 0\n; \tdiv cx\n; \tpush ax\n; \tmov ax, ss:[bp]\n; \tdiv cx\n; \tmov cx, dx\n; \tpop dx\n\n; \tadd sp, 2\n; \tadd cx, 30h\n; \tmov es:[bx], cl\n; \tdec bx\n\n; \tret\n; ;-------------------------------------------------------------------\n; isShortDiv:;[dx][ax]以十进制写入es:[bx]中 bx递减 的除法实现\n; \tmov cx, dx\n; \tjcxz shortDiv\n; \tcall long_div\n; \tjmp isShortDiv\n\t\n; divRet:\tret\n\n; shortDiv:\n; \tmov cx, 10\n; \tdiv cx\t\t\t;除法非常消耗cpu性能\n; \tadd dx, 30h\n; \tmov es:[bx], dl\n; \tmov dx, 0\n; \tdec bx\n; \tmov cx, ax\n; \tjcxz divRet\n; \tjmp shortDiv\n; ;-------------------------------------------------------------------\n; input_string:\n; \t;将dx，ax的内容以十进制的形式写入stringsg的段中\n; \tpush ax\n; \tpush cx\n; \tpush dx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; \tmov bx, stringsg\n; \tmov es, bx\n; \tmov bx, 9\n; \tcall isShortDiv\n\n; \tpop di \n; \tpop si \n; \tpop es\n; \tpop ds\n; \tpop dx\n; \tpop cx\n; \tpop ax\t\n\n; \tret\n; ;-------------------------------------------------------------------\n; show_string:\t;将ds:[si]开始不为零的字符串写入es:[di]中\n; \tpush bx\n; \tpush cx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; showString:\tmov ch, 0\n; \tmov cl, ds:[bx+1]\n; \tjcxz show_string_ret\n; \tmov es:[di], cl \n; \tadd di, 2\n; \tinc bx\n; \tjmp showString\n; show_string_ret:\n; \tpop di\n; \tpop si\n; \tpop es\n; \tpop ds\n; \tpop cx\n; \tpop bx\n; \tret\n; ;-------------------------------------------------------------------\n; show_sum:\t;以十进制形式显示ds:[si+5]开始的四个字节的内容（数值显示）\n; \tpush ax\n; \tpush bx\n; \tpush dx\n; \tpush ds\n; \tpush si\n; \tpush di\n; \tmov ax, ds:[si+5]\n; \tmov dx, ds:[si+7]\n; \tcall input_string\t;这句结束之后string中是十进制的字符了\n; \t\t\t;结束之后bx指向string中第一个有意义的字符\n; \tmov ax, stringsg\n; \tmov ds, ax\t\t\t\n; \tmov si, 0\t\t;ds:[si]\n\n; \tadd di, 15 * 2\t;es:[di] 这儿修改总收入开始列\n; \tcall show_string\n\n; \tpop di\n; \tpop si\n; \tpop ds\n; \tpop dx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;-------------------------------------------------------------------\n; show_num:\t\n; \tpush ax\n; \tpush bx\n; \tpush dx\n; \tpush ds\n; \tpush si\n; \tpush di\n\n; \tmov ax, ds:[si+10]\n; \tmov dx, 0\n; \tcall input_string \t;这句结束之后string中是十进制的字符了\n; \t\t\t;结束之后bx指向string中第一个有意义的字符\n\n; \tmov ax, stringsg\n; \tmov ds, ax\t\t\t\n\n; \tadd di, 30 * 2\t;es:[di] 这儿修改雇员数开始列\n; \tcall show_string\n\n; \tpop di\n; \tpop si\n; \tpop ds\n; \tpop dx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;-------------------------------------------------------------------\n; show_salary:\t\n; \tpush ax\n; \tpush bx\n; \tpush dx\n; \tpush ds\n; \tpush si\n; \tpush di\n\n; \tmov ax, ds:[si+13]\n; \tmov dx, 0\n; \tcall input_string \t;这句结束之后string中是十进制的字符了\n; \t\t\t;结束之后bx指向string中第一个有意义的字符\n\n; \tmov ax, stringsg\n; \tmov ds, ax\t\t\t\n\n; \tadd di, 45 * 2\t;es:[di] 这儿修改人均收入开始列\n; \tcall show_string\n\n; \tpop di\n; \tpop si\n; \tpop ds\n; \tpop dx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;-------------------------------------------------------------------\n; output_table:\n; \t;要显示的内容都在ds:[si]开始的16*21字节内\n; \tmov ax, tablesg\n; \tmov ds, ax\n; \tmov si, 0\t\t;ds:[si]\n\t\n; \tmov ax, 0B800h\n; \tmov es, ax\n; \tmov di, 160 * 3;es:[di]开始显示\n\n; \tmov cx, 21\n; outputTable:\n; \tcall show_year\n; \tcall show_sum\n; \tcall show_num\n; \tcall show_salary\n; \tadd si, 16\n; \tadd di, 160\n; \tloop outputTable\n; \tret\n; ;===================================================================\n; ;-------------------------------------------------------------------\n; clear_screen:\n; \tpush ax\n; \tpush ds\n; \tpush si\n; \tpush cx\n\n; \tmov ax, 0B800h\n; \tmov ds, ax\n; \tmov si, 0\t\t;ds:[si]\n; \tmov ax, 0700h\t;ax是NULL的ascii码\n\n; \tmov cx, 2000\n; clearScreen:\n; \tmov ds:[si], ax\n; \tadd si, 2\n; \tloop clearScreen\n\n; \tpop cx\n; \tpop si\n; \tpop ds\n; \tpop ax\n; \tret\n; ;===================================================================\n; ;-------------------------------------------------------------------\n; input_table:\n; \tpush ax\n; \tpush bx\n; \tpush cx\n; \tpush dx\n; \tpush ds\n; \tpush es\n; \tpush si\n; \tpush di\n\n; \tmov bx, datasg\n; \tmov ds, bx\n; \tmov si, 0\t\t;年份与收入所在内存的起始地址\n; \tmov di, 21 * 4 * 2\t;雇员人数所在内存的起始地址\n\n; \tmov bx, tablesg\n; \tmov es, bx\n; \tmov bx, 0\t\t;数据目的内存的起始地址\n\n; \tmov cx, 21\n; transfer:\t;移动年份\n; \tpush ds:[si+0]\n; \tpop es:[bx+0]\n; \tpush ds:[si+2]\n; \tpop es:[bx+2]\n; \t;移动收入\n; \tmov ax, ds:[si+84]\n; \tmov dx, ds:[si+86]\n; \tmov es:[bx+5], ax\n; \tmov es:[bx+7], dx\n; \t;移动员工数量\n; \tpush ds:[di+0]\n; \tpop es:[bx+10]\n\n; \t;计算平均收入并移动\n; \tdiv word ptr es:[bx+10]\n; \tmov es:[bx+13], ax\n\n; \tadd si, 4\n; \tadd di, 2\n; \tadd bx, 16\n; \tloop transfer\n\n; \tpop di \n; \tpop si\n; \tpop es\n; \tpop ds\n; \tpop dx\n; \tpop cx\n; \tpop bx\n; \tpop ax\n; \tret\n; ;===================================================================\n\n; codesg ends\n\n; end start\n\n\n\n\n; ;实验10-数值显示\n; assume cs:codesg\n\n; datasg segment\n; \tdb 10 dup (0)\n; datasg ends\n\n; stacksg segment\n; \tdb 128 dup (0)\n; stacksg ends\n\n; codesg segment\n; start:\tmov bx, stacksg\t;初始化栈\n; \tmov ss, bx\n; \tmov sp, 128\n\n; \t;转换的参数\n; \tmov ax, 9768h\t;要转换数的低位\n; \tmov dx, 5ah\t\t;要转换数的高位\n; \tmov bx, datasg\n; \tmov ds, bx\t\t;转换结果保存的地方\n; \tmov si, 0\n; \tcall dtoc\n\n; \t;显示的参数\n; \tmov dh, 8\t;显示在屏幕的哪一行\n; \tmov dl, 3\t;显示在屏幕的哪一列\n; \tmov cl, 10000010B\t;闪烁1，背景3，高亮1，前景3\n; \tcall show_str\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n\n; ;--------------------------------------------------------------------\n; dtoc:\tpush di\n; \tpush cx\n; \tmov di, 0\t\t;循环次数\n\n; circulate:\tmov cx, 10\n; \tcall divdw\n; \tadd cx, 30h\n; \tpush cx\n; \tinc di\n\n; \tmov cx, ax\n; \tjcxz jump_out\n\n; \tjmp circulate\n\n\n; ;---------------------------------------------\n; jump_out:\t\n; \tmov cx, di\t\n; ;--------------------------\n; write:\tpop ds:[si]\n; \tinc si\n; \tloop write\n; \tmov byte ptr ds:[si], 0\t\t;以0结尾\n; \tmov si, 0\n; ;==========================\n; ;=============================================\n; \tpop cx\n; \tpop di\n; \tret\n; ;=====================================================================\n\n\n; ;---------------------------------------------------------------------\n; divdw:\tpush bx\t;用来暂存中间商\n\n; \tpush ax\t;将被除数低16位入栈\n\n; \tmov ax, dx\n; \tmov dx, 0\n; \tdiv cx\t;div之后dx中存放余数，ax中存放高位除以除数的商\n\n; \tmov bx, ax\t;暂存商，累加到最终结果的dx中\n\n; \tpop ax\n\n; \tdiv cx\t;div之后dx存放余数，ax中存放商\n\n; \tmov cx, dx\n; \tmov dx, bx\n\n; \tpop bx\n\n; \tret\n; ;=====================================================================\n\n; show_str:\tpush es\n; \tpush di\n; \tpush ax\n\n; \tmov ax, 0B800h\n; \tmov es, ax\n\n; \tmov al, 0a0h\n; \tdec dh\n; \tmul dh\n; \tmov di, ax\n\n; \tmov al, 2\n; \tdec dl\n; \tmul dl\n; \tadd di, ax\t;es:[di]\n\n; \tmov al, cl\n; show_char:\tmov ch, 0\n; \tmov cl, ds:[si]\n; \tjcxz ok\n; \tmov ch, al\n; \tmov es:[di], cx\n; \tadd di, 2\n; \tinc si\n; \tjmp show_char\n\n; ok:\tpop ax\n; \tpop di\n; \tpop es\n; \tret\n\n; codesg ends\n\n; end start\n\n\n\n\n\n; ;实验10-解决除法溢出的问题\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; datasg segment\n; \tdd 1234567\n; datasg ends\n\n; stacksg segment\n; \tdb 128 dup (0)\n; stacksg ends\n\n; codesg segment\n; start:\tmov ax, stacksg\t;初始化栈\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tmov ax, datasg\n; \tmov ds, ax\n\n; \tmov ax, 0D687h\n; \tmov dx, 0012h\n; \tmov cx, 0ah\n; \tcall divdw\n\n; \tmov ax, 4c00h\n; \tint 21h\n; ;----------------------------------------------------\n; divdw:\tpush bx\t;用来暂存中间商\n; \tpush ax\t;将被除数低16位入栈\n\n; \tmov ax, dx\n; \tmov dx, 0\n; \tdiv cx\t;div之后dx中存放余数，ax中存放高位除以除数的商\n\n; \tmov bx, ax\t;暂存商，累加到最终结果的dx中\n\n; \tpop ax\n\n; \tdiv cx\t;div之后dx存放余数，ax中存放商\n\n; \tmov cx, dx\n; \tmov dx, bx\n\n; \tpop bx\n; \tret\n; codesg ends\n\n; end start\n\n; ;实验10-显示字符串\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; stacksg segment\n; \tdb 64 dup (0)\n; stacksg ends\n\n; datasg segment\n; \tdb 'Welcome to masm!', 0\n; datasg ends\n\n; codesg segment\n; start:\tmov ax, stacksg\t;初始化栈\n; \tmov ss, ax\n; \tmov sp, 64\n\t\n; \tmov dh, 8\t\t;dx\n; \tmov dl, 3\n; \tmov cl, 2\t\t;cx\n; \tmov ax, datasg\n; \tmov ds, ax\t\t;ds:[si]\n; \tmov si, 0\n\n; \tcall show_str\n\n; \tmov ax, 4c00h\n; \tint 21h\n; ;------------------------------------------------------\n; show_str:\tpush es\n; \tpush di\n; \tpush ax\n\n; \tmov ax, 0B800h\n; \tmov es, ax\n\n; \tmov al, 0a0h\n; \tdec dh\n; \tmul dh\n; \tmov di, ax\n\n; \tmov al, 2\n; \tdec dl\n; \tmul dl\n; \tadd di, ax\t;es:[di]\n\n; \tmov al, cl\n; show_char:\tmov ch, 0\n; \tmov cl, ds:[si]\n; \tjcxz ok\n; \tmov ch, al\n; \tmov es:[di], cx\n; \tadd di, 2\n; \tinc si\n; \tjmp show_char\n\n; ok:\tpop ax\n; \tpop di\n; \tpop es\n; \tret\n; ;=======================================================\n; codesg ends\n\n; end start\n\n; ;实验9\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; datasg segment\n; \t   ;0123456789ABCDEF\n; \tdb 'welcome to masm!'\n; \tdb 00000010B\n; \tdb 10100100B\n; \tdb 11110001B\n; datasg ends\n\n; stacksg segment\n; \tdb 128 dup (0)\n; stacksg ends\n\n; codesg segment\n; start:\tmov ax, stacksg\t;初始化栈\n; \tmov ss, ax\n; \tmov sp, 128\n\n; \tjmp show_masm\n\n; ;----------------------------------------\n; next:\tmov ax, 4c00h\n; \tint 21h\n\n; ;----------------------------------------\n; show_masm:\t\n; \tmov ax, datasg\n; \tmov ds, ax\n\n; \tmov ax, 0B800h\n; \tmov es, ax\n; \tmov di, 160*11 + 32*2\t;es:[di]\n\n; \tmov bx, 16\t\t;ds:[bx]\n; \tmov cx, 3\n; show_line:\tpush cx\n; \tpush di\n; \tmov si, 0\t\t;ds:[si]\n; \tmov cx, 16\n; \tmov dh, [bx]\n\n; show_str:\tmov dl, [si]\n; \tmov es:[di], dx\n; \tadd di, 2\n; \tinc si\n; \tloop show_str\n\n; \tinc bx\n; \tpop di\n; \tadd di, 160\n; \tpop cx\n; \tloop show_line\n\n; \tjmp next\n; codesg ends\n\n; end start\n\n\n; ;实验8\n; assume cs:codesg\n; codesg segment\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; start:\n; \tmov ax, 0\n\n; s:\tnop\n; \tnop\n; \tmov di, offset s\n; \tmov si, offset s2\n; \tmov ax, cs:[si]\n; \tmov cs:[di], ax\n\n; s0:\tjmp short s\n\n; s1:\tmov ax, 0\n; \tint 21h\n; \tmov ax, 0\n\n; s2:\tjmp short s1\n; \tnop\n; codesg ends\n; end start\n\n\n;附录3\n; assume cs:codesg\n; codesg segment\n; s:\tjmp s\n; \tjmp short s\n; \tjmp near ptr s\n; \tjmp far ptr s\n; codesg\t ends\n; end\n\n; assume cs:codesg\n; codesg segment\n; s:\tdb 100 dup (0b8h, 0, 0)\n; \t;jmp short s\n; \tjmp s\n; \tjmp near ptr s\n; \tjmp far ptr s\n; codesg\tends\n; end\n\n; assume cs:code\n; code segment\n; begin:\n; \tjmp short s\n; \tjmp s\n; \tjmp near ptr s\n; \tjmp far ptr s\n; s:\tmov ax, 0\n; code ends\n; end begin\n\n; assume cs:code\n; code segment\n; begin:\n; \t;jmp short s\n; \tjmp s\n; \tjmp near ptr s\n; \tjmp far ptr s\n; \tdb 100 dup (0b8h, 0, 0)\n; s:\tmov ax, 2\n; code ends\n; end begin\n\n; ;第八章实验7\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; datasg segment\n; \tdb '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983'\n; \tdb '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992'\n; \tdb '1993', '1994', '1995'\n; \t;以上表示21年的21个字符串\n; \tdd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 87479, 140417, 197514\n; \tdd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000\n; \t;以上表示21年公司收入的21个dword型数据\n; \tdw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226\n; \tdw 11542, 14430, 15257, 17800\n; \t;以上表示21年公司雇员人数的21个word型数据\n; datasg ends\n\n; table segment\n; \tdb 21 dup ('year summ ne ?? ')\n; table ends\n\n; ;栈段，多层循环中保存cx\n; stacksg segment\n; \tdw 0, 0, 0, 0, 0, 0, 0, 0\n; stacksg ends\n\n; codesg segment\n; start:\n; \t;初始化栈\n; \tmov ax, stacksg\n; \tmov ss, ax\n; \tmov sp, 10h\n; \t;初始化原数据指针\n; \tmov ax, datasg\n; \tmov ds, ax\n; \tmov bx, 0\n; \t;初始化指向table指针\n; \tmov ax, table\n; \tmov es, ax\n; \tmov bp, 0\n\n; \t;移动年份与收入\n; \tmov si, 0;表示年份与总收入的偏移量（因为两个都是4字节，可以一起表示）\n; \tmov di, 0;表示雇员数据的偏移量\n; \tmov cx, 21\n\n; s0:\tpush cx\n\n; \tmov cx, 2\n; \ts1:\t;mov word ptr es:[bp].0[di], ds:[bx].0[si]\n; \t\t;mov不能直接内存到内存，必须reg中转\n; \t\tmov ax, ds:[bx].0[si];移动年份\n; \t\tmov es:[bp].0[di], ax;无显性短地址使用[bp]时段地址默认保存在ss中，所以要显性给出段地址\n; \t\t;mov word ptr es:[bp].5[di], ds:[bx].84[si]\n; \t\tmov ax, ds:[bx].84[si];移动公司总收入\n; \t\tmov es:[bp].5[di], ax\n; \t\tinc si\n; \t\tinc si;年份与收入的偏移量\n; \t\tinc di\n; \t\tinc di;table中的偏移量\n; \t\tloop s1\n; \tmov di, 0;根据table的结构化数据，偏移量要重置\n; \tadd bp, 10h;将bp指向table下一个结构项\n; \tpop cx\n; \tloop s0\n\n; \t;移动雇员人数\n; \tmov si, 0\n; \tmov bp, 0\n; \tmov cx, 21\n; s2:\t;mov word ptr es:[bp].10, ds:[bx].168[si]\n; \tmov ax, ds:[bx].168[si]\n; \tmov es:[bp].10, ax\n; \tinc si\n; \tinc si\n; \tadd bp, 10h\n; \tloop s2\n\n; \t;计算人均收入\n; \tmov bp, 0\n; \tmov cx, 21\n; \t;32位除以16位\n; s3:\tmov ax, es:[bp].5;低位保存在ax中\n; \tmov dx, es:[bp].7;高位保存在dx中\n; \tdiv word ptr es:[bp].10;div 内存\n; \tmov es:[bp].13, ax;将商移动到内存中\n; \tadd bp, 10h;指向下一个结构项\n; \tloop s3\n\n; \tmov ax, 4c00h\n; \tint 21h\n\n; codesg ends\n\n; end start\n\n; ;问题7.9\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; stacksg segment\n; \tdw 0, 0, 0, 0, 0, 0, 0, 0\n; stacksg ends\n\n; datasg segment\n; \tdb '1. display      '\n; \tdb '2. brows        '\n; \tdb '3. replace      '\n; \tdb '4. modify       '\n; datasg ends\n\n; codesg segment\n; start:\n; \tmov ax, stacksg\n; \tmov ss, ax\n; \tmov sp, 10h\n\n; \tmov ax, datasg\n; \tmov ds, ax\n; \tmov bx, 0\n\n; \tmov cx, 4\n; s0:\tpush cx\n; \tmov si, 3\n\n; \tmov cx, 4\n; \ts1:\tmov al, [bx+si]\n; \t\tand al, 11011111B\n; \t\tmov [bx+si], al\n; \t\tinc si\n; \t\tloop s1\n\n; \tadd bx, 10h\n; \tpop cx\n; \tloop s0\n\n; \tmov ax, 4c00h\n; \tint 21h\n; codesg ends\n\n; end start\n\n; ;问题7.7/7.8\n; assume cs:codesg, ds:datasg, ss:stacksg\n\n; datasg segment\n; \tdb 'ibm             '\n; \tdb 'dec             '\n; \tdb 'dos             '\n; \tdb 'vax             '\n; datasg ends\n\n; stacksg segment\n; \tdw 0, 0, 0, 0, 0, 0, 0, 0\n; stacksg ends\n\n; codesg segment\n; start:\n; \tmov ax, stacksg\n; \tmov ss, ax\n; \tmov sp, 10h\n\n; \tmov ax, datasg\n; \tmov ds, ax\n; \tmov bx, 0\n\n; \tmov cx, 4\n; s0:\tpush cx\n; \tmov si, 0\n; \tmov cx, 3\n; \ts1:\tmov al, [bx+si]\n; \t\tand al, 11011111B\n; \t\tmov [bx+si], al\n; \t\tinc si\n; \t\tloop s1\n; \tadd bx, 16\n; \tpop cx\n; \tloop s0\n\n; \tmov ax, 4c00h\n; \tint 21h\n; codesg ends\n\n; end start\n\n; ;问题7.6\n; assume cs:codesg, ds:datasg\n\n; datasg segment\n; \tdb '1. file         '\n; \tdb '2. edit         '\n; \tdb '3. search       '\n; \tdb '4. view         '\n; \tdb '5. options      '\n; \tdb '6. help         '\n; datasg ends\n\n; codesg segment\n; start:\n; \tmov ax, datasg\n; \tmov ds, ax\n; \tmov si, 3\n; \tmov bx, 0\n\n; \tmov cx, 6\n; s:\tmov al, [bx+si]\n; \tand al, 11011111B\n; \tmov [bx+si], al\n; \tadd bx, 16\n; \tloop s\n\n; \tmov ax, 4c00h\n; \tint 21h\n; codesg ends\n\n; end start\n\n\n;第七章大小写字母转换\n; assume cs:codesg, ds:datasg\n\n; datasg segment\n; \tdb 'BaSiC'\n; \tdb 'iNfOrMaTiOn'\n; datasg ends\n\n; codesg segment\n; start:\n; \tmov ax, datasg\n; \tmov ds, ax\n\n; \tmov bx, 0\n\n; \tmov cx, 5\n; s1:\tmov al, [bx]\n; \tand al, 11011111B\n; \tmov [bx], al\n; \tinc bx\n; \tloop s1\n\n; \tmov cx, 11\n; s2:\tmov al, [bx]\n; \tor al, 00100000B\n; \tmov [bx], al\n; \tinc bx\n; \tloop s2\n\n; \tmov ax, 4c00h\n; \tint 21h\n; codesg ends\n\n; end start\n\n\n; ;实验5 - （6）\n; assume cs:code\n\n; a segment\n; \tdw 1, 2, 3, 4, 5, 6, 7, 8, 9, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh, 0ffh\n; a ends\n\n; b segment\n; \tdw 0, 0, 0, 0, 0, 0, 0, 0\n; b ends\n\n; code segment\n; start:\n; \tmov ax, a\n; \tmov ds, ax\n; \tmov ax, b\n; \tmov ss, ax\n; \tmov sp, 10h\n\n; \tmov bx, 0\n\n; \tmov cx, 8\n; s:\tpush [bx]\n; \tinc bx\n; \tinc bx\n; \tloop s\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n;实验5 - （5）\n; assume cs:code\n\n; a segment\n; \tdb 1, 2, 3, 4, 5, 6, 7, 8\n; a ends\n\n; b segment\n; \tdb 1, 2, 3, 4, 5, 6, 7, 8\n; b ends\n\n; c segment\n; \tdb 0, 0, 0, 0, 0, 0, 0, 0\n; c ends\n\n; code segment\n; start:\n; \tmov ax, a\n; \tmov ds, ax\n\n; \tmov bx, 0\n\n; \tmov cx, 8\n; s:\tmov al, 0\n; \tadd al, [bx]\n; \tadd al, [bx+16]\n; \tmov [bx+32], al\n; \tinc bx\n; \tloop s\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; end start\n\n;实验5 - （1）（2）（3）（4）\n; assume cs:code, ds:data, ss:stack\n\n; code segment\n; start:\n; \tmov ax, stack\n; \tmov ss, ax\n; \tmov sp, 16\n\n; \tmov ax, data\n; \tmov ds, ax\n\n; \tpush ds:[0]\n; \tpush ds:[2]\n; \tpop ds:[2]\n; \tpop ds:[0]\n\n; \tmov ax, 4c00h\n; \tint 21h\n; code ends\n\n; data segment\n; \tdw 0123h, 0456h;, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h\n; data ends\n\n; stack segment\n; \tdw 0, 0;, 0, 0, 0, 0, 0, 0\n; stack ends\n\n; end start"
  }
]