assembly - 为什么中断int 21h在程序执行期间写入填充的字符串后会忽略所有字符串?
问题描述
我正在尝试打印两个 16Bit 值的总和,因此正在计算总和然后构造包含它的字符串,但问题是在我打印所述字符串后,任何写入中断mov ah,09 int 21h
都将被完全忽略,我使用的是 emu8086,这是代码
org 100h
mov ax,2000
mov bx,3200
add ax,bx
mov si,offset result+5
mov [si],'$'
mov bx,10
Fill:
dec si
mov dx,0
div bx
add dl,48
mov [si],dl
test ax,ax
jnz Fill
mov dx,offset result
mov ah,09h
int 21h
mov ah,09h
mov dx,offset msg
int 21h
ret
result db 5 dup (?)
msg db " is the sum$"
\n db 0ah,0dh, '$'
它只是打印result
并忽略msg
解决方案
result db 5 dup (?) msg db " is the sum$"
使用这些数据定义,内存设置如下:
result 0 <- offset result+0
0 <- offset result+1
0 <- offset result+2
0 <- offset result+3
0 <- offset result+4
msg <- offset result+5 <- offset msg+0
i <- offset msg+1
s <- offset msg+2
<- offset msg+3
t <- offset msg+4
h <- offset msg+5
e <- offset msg+6
<- offset msg+7
s <- offset msg+8
u <- offset msg+9
m <- offset msg+10
$ <- offset msg+11
当您在 处为结果编写终止 $时offset result+5
,您会覆盖msg文本开始的那个空格字符。这反过来意味着当您要求 DOS 显示msg文本时,DOS 会立即偶然发现字符串终止符,因此不会显示任何内容。
解决方案是不要将 $ 字符写在offset result+4
相反,您需要为结果扩大缓冲区,以便它可以容纳6个字节。
您转换的寄存器中的值AX
可能需要 5 位数字。因此,您需要一个 5+1 字节的缓冲区。
result db 6 dup (?)
作为避免必须通过代码编写 $ 字符的快捷方式,有:
result db 5 dup (?), '$'
mov dx,offset result mov ah,09h int 21h
使用结果的偏移量可能会在屏幕上产生垃圾!
这里好的解决方案是SI
在转换结束时使用寄存器中的值。它已经指向数字的第一位。多么方便!
org 100h
mov ax, 2000
mov bx, 3200
add ax, bx
mov si, offset result+5
mov [si], '$'
mov bx, 10
Fill:
dec si
xor dx, dx
div bx
add dl, '0'
mov [si], dl
test ax, ax
jnz Fill
mov dx, si <- This is offset of first digit.
mov ah, 09h
int 21h
mov ah, 09h
mov dx, offset msg
int 21h
ret
result db 6 dup (?)
msg db " is the sum$"
推荐阅读
- reactjs - 尝试在Formik中更改onChange时无法输入
- java - List.stream 映射非静态方法不能从静态上下文中引用
- javascript - SyntaxError:无法在模块 Typescript 错误之外使用 import 语句
- discord - 机器人旨在随机标记服务器中的某人仅标记自身
- javascript - JS全局变量在函数范围之外没有改变
- node.js - MERN stack 如何将联系人添加到组?
- python - 无法使用 Python 3.9 转换 mp3
- graph - 在邻接表中计算入度的复杂度是O(|E|)?
- windows - 自定义屏幕保护程序 - windows
- android - Firebase StreamBuilder 错误