我是汇编新手,我关注的课程使用 EMU8086 。我写了这段代码来打印Testing
和ASCII码50,它是数字2
,但它只打印Testing
并忽略其余的。怎么了?
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 4ch
mov dx ,0
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
在阅读@ 500 - 内部服务器错误的评论后,我将我的代码更新为:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
它仍然无法正常工作,那有什么不对?
答案 0 :(得分:1)
DOS 中断INT 21h/AH=9h不会打印字符值,它会将内存偏移量移到要打印的procedure TForm1.LoadFile(const AFilename: String);
var
I: TIniFile;
L: TStringList;
X: Integer;
N: String;
V: String;
begin
I:= TIniFile.Create(AFilename);
try
L:= TStringList.Create;
try
ComboBox1.Items.Clear;
I.ReadSectionValues('Colours', L);
for X := 0 to L.Count-1 do begin
N:= L.Names[X]; //The Name
V:= L.Values[N]; //The Value
ComboBox1.Items.Add(V);
end;
finally
L.Free;
end;
finally
I.Free;
end;
end;
终止字符串的开头。
DOS 1+ - 写入标准输出字符串
AH = 09h
DS:DX - > '$' - 终止字符串
返回:
AL = 24h('$'终止字符串,尽管官方文档声明没有返回任何内容)(至少DOS 2.1-7.0和NWDOS)
如果要使用 INT 21h / AH = 9h 打印单个字符,则需要将值移动到以$
符号终止的缓冲区中。然后,将该缓冲区的地址传递给 INT 21h / AH = 9h 。根据你的第二个例子,这样的事情应该有效:
$
而不是.model tiny
.code
org 100h
main proc
mov ah, 09h ; DOS Interrupt ah=9h print $ terminated string
mov dx, offset msg ; Address of msg
int 21h ; Int 21h/ah=9h Print msg
mov outchar, 48+2 ; Move ASCII val for `2` to outchar buffer
mov dx, offset outchar ; Address of the $ terminated outchar buffer in DX
int 21h ; AH is still 9h, so this prints $ terminated string
mov ax, 4c00h ; Exit program with return value 0
int 21h
endp
msg db "Testing$" ; msg string
outchar db ?, "$" ; output buffer for single character terminated with $
end main
你可以像这样使用ASCII值:
mov outchar, 48+2
或者你可以通过一次调用 INT 21h / AH = 9h 来做到这一点,方法是将你想要的字符放在输出缓冲区的中间:
mov outchar, '2'
这样做的原因是因为 INT 21h / AH = 9h 将盲目地打印从偏移main proc
mov outchar, '2' ; Place the ASCII value for '2' in the output buffer
mov ah, 09h
mov dx, offset msg
int 21h ; Print $ terminated string starting at `msg`
mov ax, 4c00h
int 21h ; Exit with error code 0
endp
msg db "Testing"
outchar db ?, "$"
开始找到的所有内容,直到找到msg
终止字符。我们首先在$
处有效地替换字符,这样当 INT 21h / AH = 9h 执行时,它将在内存中遇到outchar
。
一旦到达Testing2$
,它将停止打印,因此输出将如下所示:
Testing2
您还可以选择使用两个不同的DOS(INT 21h)中断。当 INT 21h / AH = 9h 打印一个$
终止的字符串时,INT 21h/AH=2h会显示一个字符:
DOS 1+ - 标准输出的写字符
AH = 02h
DL =要写的字符
返回: AL =最后一个字符输出(尽管官方文档说明了 什么都没有返回)(至少DOS 2.1-7.0)
您可以将程序编码为显示$
字符串,但之后您可以使用 INT 21h / AH = 2h 来显示单个字符。您的代码可能如下所示:
msg
答案 1 :(得分:1)
您的第二个代码几乎没问题,您只忘记ah
中的服务号码,告诉int 21h
该做什么:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 2 ;<==== AH=2 : INT 21H WILL DISPLAY CHARACTER IN DL.
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main