实验九
这是调试的样子呜呜{:5_99:}
而且,显示字符串以后dosbox就会卡住,没法再输入指令{:10_243:}
代码如下:
assume cs: codesg, ds: data, ss: stack
data segment
db 'welcome to masm!' ; 在显存显示的字符串(16个字符,需要占32个字节,一个字节存放asc码,一个字节存放字符属性)
db 02h, 24h, 71h ; 定义三种颜色属性(黑底绿字, 绿底红字, 白底蓝字)
data ends
stack segment
dw 8 dup(0) ; 定义8个字型数据用于存放寄存器的值
stack ends
codesg segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 10h ; 设置栈顶,八个字型数据占16个字节,故偏移地址取10h
xor bx, bx ; bx清零, 用来索引属性
mov ax, 0b872h ; 定位第十二行中间位置(作段地址使用): (11 * 160 + (80 - 16) / 2 * 2)在转换为16进制
mov cx, 3 ; 执行三次循环,打印三行语句
s3:
push cx ; 为外循环保存相关寄存器的值
push ax ; 防止段地址的值在内循环中被改变
push bx
mov es, ax ; 此时es为显存的段地址
mov si, 0 ; si用于索引字符
mov di, 0 ; di用于定位字符存往的es段的偏移地址
mov cx, 10h
; s1控制存放的字符,内循环为10h次,因为一行含10h个字节(注意!十六进制的10表示十进制的16)
s1:
mov al, ds:
mov es:, al
inc si
add di, 2
loop s1
; 将字符存入偶数偏移地址
mov di, 1
pop bx
mov al, ds:10h ; 取出字符串属性赋给al
inc bx ; ds:指向下一行字符串的属性
mov cx, 10h
s2:
mov es:, al
add di, 2
loop s2
; 存入字符属性
pop ax
add ax, 00A0H ; 将段地址修改到下一行
loop s3
mov ax, 4c00h
int 21h
codesg ends
end start
1. 在执行58行的 loop s3 之前,没有 pop cx
2. 27行的 push bx 和45行的 pop bx 之间修改过bx寄存器吗?为什么要保存bx ?
3. 代码成对编写就不会出现这样的问题
mov cx, 10h
mov cx, 10h
s3:
loop s3
mov cx, 10h
s3:
push cx
pop cx
loop s3
mov cx, 10h
s3:
push cx
push ax
pop ax
pop cx
loop s3
像这样,一对一对的写,这样就不会漏掉 pop cx 了 mov cx, 10h
s3:
push cx
push ax
; 其他代码继续在这里写
pop ax
pop cx
loop s3 人造人 发表于 2022-6-29 19:37
我改了一下,但是还是只能打印出一行,而且打印出来的是"Aelcome to masm!", 第一个字符有问题,可以麻烦再帮我看一下是哪里有问题吗{:10_266:}
assume cs: codesg, ds: data, ss: stack
data segment
db 'welcome to masm!' ; 在显存显示的字符串(16个字符,需要占32个字节,一个字节存放asc码,一个字节存放字符属性)
db 02h, 24h, 71h ; 定义三种颜色属性(黑底绿字, 绿底红字, 白底蓝字)
data ends
stack segment
dw 8 dup(0) ; 定义8个字型数据用于存放寄存器的值
stack ends
codesg segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 10h ; 设置栈顶,八个字型数据占16个字节,故偏移地址取10h
xor bx, bx ; bx清零, 用来索引属性
mov ax, 0b872h ; 定位第十二行中间位置(作段地址使用): (11 * 160 + (80 - 16) / 2 * 2)在转换为16进制
mov cx, 3 ; 执行三次循环,打印三行语句
s3:
push cx ; 为外循环保存相关寄存器的值
push ax ; 防止段地址的值在内循环中被改变
; push bx
mov es, ax ; 此时es为显存的段地址
mov si, 0 ; si用于索引字符
mov di, 0 ; di用于定位字符存往的es段的偏移地址
mov cx, 10h
; s1控制存放的字符,内循环为10h次,因为一行含10h个字节(注意!十六进制的10表示十进制的16)
s1:
mov al, ds:
mov es:, al
inc si
add di, 2
loop s1
; 将字符存入偶数偏移地址
mov di, 1
; pop bx
mov al, ds:10h ; 取出字符串属性赋给al
inc bx ; ds:指向下一行字符串的属性
mov cx, 10h
s2:
mov es:, al
add di, 2
loop s2
; 存入字符属性
pop ax
pop cx
add ax, 00A0H ; 将段地址修改到下一行
loop s3
mov ax, 4c00h
int 21h
codesg ends
end start
本帖最后由 jackz007 于 2022-6-30 00:22 编辑
assume cs: code , ds: data
data segment para public 'data'
db 'welcome to masm!'
db 02h , 24h , 71h
data ends
stack segment para stack 'stack' ; 这样定义,编译器能够识别出堆栈段,并自动对号入座 ss 和 sp,不必专门用代码进行初始化。
dw 800h dup(0) ; 必须定义足够大的堆栈空间,否则,如果堆栈空间不够使用,程序将无法正常运行,甚至可能直接奔溃。
stack ends
code segment para public 'code'
start:mov ax, data
mov ds, ax
mov ax,0b800h
mov es,ax
mov di,726h
xor bx,bx
mov cx,3
cld
s1: push cx
xor si,si
mov cx,10h
s2: movsb
mov al,
stosb
loop s2
inc bx
pop cx
add di,128
loop s1
xor ax,ax
int 16h
mov ax,4c00h
int 21h
code ends
end start 6YKT6ZKm5LqI 发表于 2022-6-29 23:30
我改了一下,但是还是只能打印出一行,而且打印出来的是"Aelcome to masm!", 第一个字符有问题,可以麻烦 ...
add ax, 00A0H ; 将段地址修改到下一行
下一行是加 a0 吗?
下一行应该加多少?
试试这个
add ax, 0AH 6YKT6ZKm5LqI 发表于 2022-6-29 23:30
我改了一下,但是还是只能打印出一行,而且打印出来的是"Aelcome to masm!", 第一个字符有问题,可以麻烦 ...
Aelcome to masm
不要忘了你用的debug程序调试的程序
debug程序也要写显存的,而且是你的程序先写,debug程序后写
你的程序先写了一个w,然后debug程序又写了一个A,正好覆盖了你的程序写的那个w
如果debug程序不写显存的话,你怎么能从屏幕上看到当前执行的哪条指令,当前寄存器中的值
debug程序把这些数据写到显存,然后你就从屏幕上看到了
{:5_108:} {:7_146:}
页:
[1]