鱼C论坛

 找回密码
 立即注册
查看: 1746|回复: 0

[汇编作业] 实验16——为了节约内存,拼了。。。

[复制链接]
发表于 2015-6-9 23:26:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在正式开始做实验16之前,我不知道0:200到0:2ff的空间够不够放得下四个子程序。

在看16.4的时候,我发现子程序2和子程序3的功能基本相同,一个是改前景色,一个是改背景色,代码也基本相同。我想,既然不能确定内存空间够不够,干脆就采用最节约的方式吧,把程序2和程序3做成一个程序

当然了,我遇到了大家初次做实验16应该都会遇到的问题,就是假如采用16.4的思路,直接定址表中的内存地址在安装之后是错的。笨人当然有笨人的策略,于是我就这样做了:
  1. assume cs:code

  2. stack segment stack
  3.         dw 32 dup(0)
  4. stack ends

  5. code segment
  6. start:  mov ax, cs
  7.         mov ds, ax
  8.         mov si, offset int7ch
  9.         
  10.         xor ax, ax
  11.         mov es, ax
  12.         mov di, 200h
  13.         
  14.         mov cx, offset int7chend - offset int7ch
  15.         cld
  16.         rep movsb
  17.         
  18.         cli
  19.         mov word ptr es:[7ch * 4], 200h
  20.         mov word ptr es:[7ch * 4 + 2], 0h
  21.         sti
  22.         
  23.         mov ax, 4c00h
  24.         int 21h
  25.         
  26. int7ch: jmp short screenstart
  27.         dw sub1 - int7ch + 200h, sub23 - int7ch + 200h, sub23 - int7ch + 200h, sub4 - int7ch + 200h
  28.         
  29. screenstart:
  30.         push bx
  31.         cmp ah, 3
  32.         ja quit
  33.         
  34.         mov bl, ah
  35.         xor bh, bh
  36.         add bx, bx
  37.         
  38.         call word ptr cs:[bx + 202h]
  39.         
  40. quit:   pop bx
  41.         iret
  42.         
  43. sub1:   push cx
  44.         push ds
  45.         push si
  46.         
  47.         mov si, 0b800h
  48.         mov ds, si
  49.         mov si, 0
  50.         
  51.         mov cx, 4000h
  52. sub1s:  mov byte ptr [si], 0
  53.         add si, 2
  54.         loop sub1s
  55.         
  56.         pop si
  57.         pop ds
  58.         pop cx
  59.         ret
  60.         
  61.         ; 子程序2和3的功能类似,合并为一了
  62. sub23:  push bx
  63.         push cx
  64.         push ds
  65.         push si
  66.         
  67.         jmp sub23switch
  68.         submask db 11111000b, 10001111b ; 色彩掩码
  69.         bits db 0, 4 ; 移动位数
  70. sub23switch:
  71.         mov bx, 0b800h
  72.         mov ds, bx
  73.         mov si, 1
  74.         
  75.         mov bl, ah
  76.         xor bh, bh
  77.         shr bx, 1 ; 这里是将1和2对应为0和1
  78.         
  79.         ; 假如修改背景色,al是要左移4位的
  80.         mov cl, cs:[bits - int7ch + 200h][bx]
  81.         shl al, cl
  82.         mov bl, cs:[submask - int7ch + 200h][bx]
  83.         
  84.         mov cx, 2000h
  85. sub23s: and [si], bl
  86.         or [si], al
  87.         add si, 2
  88.         loop sub23s
  89.         
  90.         pop si
  91.         pop ds
  92.         pop cx
  93.         pop bx
  94.         ret
  95.         
  96. sub4:   push cx
  97.         push ds
  98.         push es
  99.         push si
  100.         push di
  101.         
  102.         mov si, 0b800h
  103.         mov ds, si
  104.         mov es, si
  105.         mov si, 80 * 2
  106.         mov di, 0
  107.         
  108.         cld
  109.         mov cx, 24
  110. sub4s:  push cx
  111.         mov cx, 160
  112.         rep movsb
  113.         pop cx
  114.         loop sub4s
  115.         
  116.         mov cx, 80
  117. sub4s1: mov byte ptr [di], 0
  118.         add si, 2
  119.         loop sub4s1
  120.         
  121.         pop di
  122.         pop si
  123.         pop es
  124.         pop ds
  125.         pop cx
  126.         ret
  127.         
  128. int7chend:
  129.         nop
  130.         
  131. code ends
  132. end start
复制代码


大约可以节省15字节的空间

定址方法并不算好,只是权宜之计。假如中断程序安装的位置发生了变化,本程序需要修改的地方还是比较多的。

下面总结两种个人认为很有价值的方案:
1、将需要安装的中断程序放在主程序前面。这样的好处在于不论在安装程序中还是在安装后的中断程序中,直接定址表中保存的偏移地址是一致的,不需要像我的程序需要大量换算。此时,中断向量表中的cs和ip就不能是0和200h了,而应该是20h和0,个中妙处实在难以言喻。
2、采用ORG伪指令。依旧是主程序在前中断程序在后,但在中断程序前加ORG 200h指令,规定下面的代码从200h开始,这样一来,直接定址表就会按照200h为基准计算偏移。
以上两种方案的优势均在于思路直观,便于修改

ps:如果采用宏,我的程序也并不是很难改的,只是我还不会 :P
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-28 11:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表