本帖最后由 x0710 于 2022-8-11 13:34 编辑
这段代码虽然简短,但是对于一个汇编初学者还是有太大难度的,7点想思路,14点开始,20:50结束。也有些经验教训。如这个程序的特征是:不能用debug,我就傻傻的debug,百思不得其解。哪怕是正确答案我结果都是错误的。走过坑后,这个要在DOS直接运行。
一个复杂的事要从简单开始,积少成多。要求是在中间显示三行welcome to masm!,简单分析下就是重复三次打印welcome,再分别设置它们的属性。如果遇到寄存器不够用的情况就使用栈,在字节与字的下标要求同步时,字节和下标可以用add bx,bx再配合栈来实现与字下标同步,还原字节下标(因为字的大小是字节的2倍原因)。<del>同时也考查了如何实现三行文字如何同步,一行有80字符,1个字符本身1字节,属性1字节,所以1个字符占2字节,合1字大小。那么一行是160字节,分左右各80字节,welcome to masm!共16字节,折半为8字节,则一行就从第80-8=72</del>????我不知我的怎么算中间为64字节了,怎么是72?(哪位大佬来指下错误)
第一行定义段地址B864(提前测量的),上面计算出偏移地址64,由我举出的数也可以发现段地址每次递增AH(不讲是因为我忘了怎么算的了,要和十进制一起算。加一句,在写教程的时候发现怎么讲了,比我当时想的简单多了)刚刚有说一行的大小是160字节,那么160=A0H,再将A0H右移4位(这里是将内存地址转为段地址,不懂请复习CUP段地址转为物理地址),(A0H>>4)=AH,所以每个地址要相隔AH大小(因为一行A0H大小,要实现两行对齐空一行就行了)。
[Asm] 纯文本查看 复制代码 assume cs:code
stack segment
dw 5 dup (0)
data segment
db 'welcome to masm!' ;first line: B864:40
db 00000010b,00100100b,01110001b
dw 0B864H,0B86eH,0b878H
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,12
mov bx,0
mov cx,3
s:push cx
push bx
add bx,bx
mov ax,19[bx]
mov es,ax
pop bx
mov ah,16[bx]
mov cx,16
push bx
mov bx,0
s0:
mov al,0[bx]
push bx
add bx,bx
mov es:64[bx],ax
pop bx
inc bx
loop s0
pop bx
inc bx
pop cx
loop s
mov ax,4c00h
int 21h
code ends
end start |