loveyzer 发表于 2015-3-2 11:14:07

实验九,想了一夜,觉得这个方法最简单明了

想了一夜,其实也是突然灵感一闪,觉得这样比较简单,麻烦大家看看,还可以再改改不,发帖少,就不隐藏了:lol:

assume cs:codesg

data segment
db 'welcome to masm!'
db02h,02h,02h,02h,02h,02h,02h,24h,24h,24h,24h,71h,71h,71h,71h,71h,71h      
data ends

codesg segment
        start: mov ax,data
             mov ds,ax
                   mov bx,0
                   mov ax,0b800h   
                   mov es,ax       
                   mov bp,720h
         mov cx,16
                  
               s:mov al,         ;地位字节控制ASCII码
                   mov ah,      ;高位字节控制字符属性
                   mov es:,ax      ;把字符与字符属性同时传送给显存
                   inc bx            
                   add bp,2               ;bp增加一个字的长度
         loop s
                  
                   mov ax,4c00h
                   int 21h
               
codesg ends
end start

鱼非子 发表于 2020-9-17 19:18:28

这样看起来是可以的,但是你忘掉了一个居中三行的外循环。
其实也可以把字节的属性作为立即数【常数】,在第一行时,把属性的源地址在ASCII字节的偏移变量上加8,再加一个偏移变量si,就可以和ASCII一起循环十六次,完成ASCII和属性的同步转移到显存中,在完成16次循环后,记得把si自加1
回头我试着把代码敲到回复里,大家一起研究研究

鱼非子 发表于 2020-9-17 21:58:18

不知道为什么,我的64位window10,在下载了DOSbox后在DOS中无法搜自己写好并放好目录中的masm文件,也就无法在DOS中一步步的debug程序,哪位大佬帮我debug下,看看有没有问题这样{:5_105:}



assumeds:datasgcs:codesg   ss:stacksg
datasg segment
          db ' welcome to masm!'
          db 02h 24h 71h
datasg ends

stacksg segment
          dw8 dup(0)
stacksg ends

codesg segment
start      mov ax,datasg    ;定义数据段段地址       
            mov ds,ax
            mov ax,stacksg   ;定义栈段段地址
            mov ss,ax
            mov sp,16   ;定义栈段指针指向栈顶
            mov ax,0b872h          ;定义字符窜在显存地址的首地址段,这里搞不懂,小甲鱼那个视频为什么把这个定义放到大循环里面
            mov es,ax
            mov bx,0      ;bx为数据段的偏移地址变量
            mov cx,3       ;总共三行,外循环次数
            mov di,0      ;定义显存中字符的基址
            
s0:       mov ax,ds:         ;这里做行的循环s0
             mov es:,ax
             push bx
             push di
             push cx
s1:      mov cx,16
             mov al,ds:;将字母字节转存到显存
             mov es::al
             mov al,ds:16   ;将字母的属性转存到显存
             mov es:1,al       ;因为字母属性前面有一个字母字节,所以它的起始地址需要向后偏移一个字节,用立即数1来实现
             inc bx,1      ;数据段中,逐一将字母字节挖出来
             add di,2   ;显存段中,将字母字节和字母属性同时入驻ds的数据
         loop s1
            pop cx
            pop di
            pop bx
            add di,160
         loop s0
mov   ax,4c00h
       int 21h
codesg ends
end start
            
            
            
            
            
            

人间凑数 发表于 2020-11-12 11:24:12

assume cs:code,ds:data

data segment
db 'welcome to masm!';可以用字符(我当时挨个查的ascll码)
db 0ah,0ach,71h;16开头
data ends

code segment
start: mov ax,data
       mov ds,ax
       mov ax,0b800h
       mov es,ax          
           mov si,0
       mov di,0
           mov dx,3
          
        s1:mov bx,0
           mov cx,16
        s: mov al,
           mov ah,
           mov es:,ax
           inc bx
           add di,2
           loop s
          
           add di,128
           inc si
           dec dx
           mov cx,dx
           jcxz s2
           jmpshort s1       

    s2:mov ax,4c00H
       int 21h          
code ends
end start
页: [1]
查看完整版本: 实验九,想了一夜,觉得这个方法最简单明了