实验十
1.
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
code segment
start: mov dh,8
mov dl,3
mov cl,2
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str: mov ax,0b800h ;存显存地址
mov es,ax
sub dl,1 ;第三列相当于在2号位
add dl,dl ;字符是两个字节组成
mov bl,dl
mov bh,0
mov di,bx ;转化为字节的列数
sub dh,1 ;第8行相当于7号位行
mov al,dh
mov ah,0
mov bx,00a0h ;一行有160个字节
mul bx ;找到字节位置
sub ax,1 ;减1得字属性位置
mov bp,ax
s: mov cx, ;判断字符串末尾
jcxz offset ok;cx为零停止
mov cl,2 ;字符绿色属性
mov al,
mov es:,al ;将字属性放入显存
mov es:,cl ;将颜色属性放入字属性后一位
add di,2 ;显存一个字符的单位
add si,1 ;数据段一个字符单位
jmp short s
ok: ret ;提取字符串到末尾返回
code ends
end start
2.
assume cs:code
data segment
dd 0,0
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,4240h
mov dx,000fh
mov cx,0ah
call divdw
mov ax,4c00h
int 21h
divdw:mov bx,ax
mov ax,dx
mov dx,bx ;互换高低位
mov si,0
mov ,dx ;将dx = 4240h暂存数据空间 00 00 00 00 42 40 00 00
div cl ;八位除数
mov bl,al
mov bh,0
mov ,bx ;将高16位的商存数据空间 01 00 00 00 42 40 00 00
mov dl,ah ;余数存dx用于下一步16位除法放入高16位相当于*65536
mov dh,0
mov ax, ;将原公式低16被除数放入ax准备运算16除法
div cx ;运算后得到的ax既为结果低16位的商 86A0
mov cx,dx ;dx为最终余数
mov word ptr dx, ;将数据空间内原本存储的高16位的商结合即为186A0
ret
code ends
end start
3.
assume cs:code
data segment
dw 123,12666,1,8,3,38
data ends
d segment
db 5 dup(0) ;d段:开辟五个字节空间暂存字符串每个字符对应的字属性
d ends
stack segment
dw 2 dup(0) ;暂存计数器
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0b800h ;存显存段地址
mov es,ax
mov ax,stack
mov ss,ax
mov sp,4
mov si,0
mov di,0
mov cx,6 ;6个字符运行六次
s:push cx
;避免cx被干扰
mov bx,0 ;dtoc中 bx作为计数器为short计算位置
mov bp,0 ;bp为d断寻址偏移
call dtoc
add si,2 ;dtoc中 si为data段中数值的偏移
mov bp,0 ;show_str中bp同样作为对d段暂存字符串字属性的使用
mov cx,bx ;将dtoc得到的bx计数器作为show_str的循环次数,这样就知道要显示的数值到底是几位数
call show_str
pop cx ;归还总体循环次数
loop s
mov ax,4c00h
int 21h
dtoc:mov ax,
mov cx,10
mov dx,0
div cx
mov ,ax
add dx,30h ;当前dx为余数,即为数值最后一位的数字 +30h为对应的ascii码
mov ds:,dl ;倒序存入d段
dec bp
inc bx ;计数器为show_str使用
mov cx,ax
jcxz short ok ;字符末尾返回
jmp short dtoc
ok: ret
show_str: mov ax,5 ;d段为五个字节
sub ax,cx ;减去dtoc得到的计数器就可得知d段中有几个字属性,从哪个字节开始将数据传入显存
mov bp,ax
mov al,ds:
mov ah,2
mov es:,ax ;1830为屏幕显示位置
add di,2
loop show_str
add di,2 ;空格隔开
ret
code ends
end start
看起来你在求助于两个不同的汇编程序,分别是一个字符串显示程序和一个双字除法程序。让我来帮助你完成这些程序,并解决其中存在的问题。
### 第一部分:字符串显示程序
目标是在特定的屏幕位置显示字符串 "Welcome to masm!"。
我们将从代码中的错误入手进行分析和修正:
1. `show_str` 子程序中缺少字符串长度的初始化。
2. 需要赋值 `es:` 处的显存地址。
3. `cx` 应该在每次循环之后递减。
修正后的代码如下:
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
code segment
start:
mov ax, data
mov ds, ax
mov dh, 8
mov dl, 3
mov si, offset data ; si 初始化为字符串的起始地址
call show_str
mov ax, 4C00h
int 21h
show_str:
mov ax, 0b800h ; 显存地址
mov es, ax
sub dh, 1 ; 转化为实际行(显示从第7行开始)
sub dl, 1 ; 转化为实际列(显示从第2列开始)
shl dl, 1 ; 每个字符占两个字节
mov di, dx ; di = dh * 160 + dl*2
shl dh, 7
shl dh, 1
add di, dh
mov cx, 16 ; 假设字符串长度为16,包括结束符
s:
mov al, ds:
cmp al, 0 ; 检测字符串结尾
je ok
mov es:, al
mov es:, 2 ; 设置颜色为绿色
add di, 2
inc si
loop s
ok:
ret
code ends
end start
### 第二部分:双字除法程序
此程序旨在实现 32 位除法,即 42400h 除以 0Ah。
我们来修复并完成这部分代码:
assume cs:code
data segment
result dd 0
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 4240h
mov dx, 0000h
push dx ; 模拟 4240h 在高位
push ax ; 模拟 0000h 在低位
pop ax
pop dx
mov cx, 0Ah ; 除数
call divdw
mov ax, 4C00h
int 21h
divdw:
mov ebx, edx: eax ; 将 ax 和 dx 组合成 32 位(edx: eax)
xor edx, edx
div cx ; 执行 32 位除法,quotient 在 eax, remainder 在 edx
mov ds: result, eax ; 存储结果
ret
code ends
end start
修正说明:
1. 我们先将 `ax` 和 `dx` 扩展成 32 位寄存器 `edx:eax`。
2. 再执行 `div` 指令。
如果两个问题都已解决或如果有进一步问题,请告诉我。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]