[英]DOS Assembler: MOV ah, 09h AND int 21h combination doesn't print anything
I'm writing a DOS commandline arguments parser on TASM assembly language. 我正在使用TASM汇编语言编写DOS命令行参数解析器。 Here's my code:
这是我的代码:
.model tiny
.386
.code
org 100h
start:
mov ax, ax
mov bp, 80h
mov si, 81h
mov ch, 0
mov cl, ds:[bp]
push 0
cmp cx, 0
je FINISH
CYCLE_BEGIN:
lodsb
cmp al, 2Fh
je SLASH
cmp al, 31h
je ONE
cmp al, 32h
je TWO
cmp al, 33h
je THREE
cmp al, 68h
je HELP
cmp al, 20h
je SPACE
mov bx, 6
jmp CHANGE_STATE
SLASH:
mov bx, 0
jmp CHANGE_STATE
ONE:
mov bx, 1
jmp CHANGE_STATE
TWO:
mov bx, 2
jmp CHANGE_STATE
THREE:
mov bx, 3
jmp CHANGE_STATE
HELP:
mov bx, 4
jmp CHANGE_STATE
SPACE:
mov bx, 5
CHANGE_STATE:
mov ax, 7
mul dx
add ax, bx
mov dh, 0
push si
mov si, offset AU
add si, ax
lodsb
mov dl, al
pop si
cmp dx, 6
JE ERROR
cmp dx, 1
je HAVEONE
cmp dx, 2
je HAVETWO
cmp dx, 3
je HAVETHREE
cmp dx, 4
je HAVEHELP
jmp CYCLE_END
HAVEONE:
mov ax, 0001h
jmp SETFLAGS
HAVETWO:
mov ax, 0010h
jmp SETFLAGS
HAVETHREE:
mov ax, 0100h
jmp SETFLAGS
HAVEHELP:
mov ax, 1000h
SETFLAGS:
pop bx
or bx, ax
push bx
CYCLE_END:
dec cx
jne CYCLE_BEGIN
jmp SUCCESS
ERROR:
pop bx
mov dx, offset merror
mov ah, 09h
int 21h
jmp FINISH
SUCCESS:
pop bx
mov dx, bx
and dx, 1000h
je MESSAGES_CHECK
mov dx, offset mhelp
mov ah, 09h
int 21h
jmp FINISH
MESSAGES_CHECK:
mov dx, bx
and dx, 0001h
je CHECK2
mov dx, offset m1
mov ah, 09h
int 21h
mov ah, 02h
mov dl, 0dh
int 21h
mov dl, 0ah
int 21h
CHECK2:
mov dx, bx
and dx, 0010h
je CHECK3
mov dx, offset m2
mov ah, 09h
int 21h
mov ah, 02h
mov dl, 0dh
int 21h
mov dl, 0ah
int 21h
CHECK3:
mov dx, bx
and dx, 0100h
je FINISH
mov dx, offset m3
mov ah, 09h
int 21h
FINISH:
RET
m1 db 'You have used /1 key$'
m2 db 'You have used /2 key$'
m3 db 'You have used /3 key$'
mhelp db 'ad.asm [/1 | /2 | /3| /h]$'
merror db 'Wrong input$'
AU:; / 1 2 3 h *
db 5,6,6,6,6,0,6 ;
db 6,6,6,6,6,0,6 ; /1
db 6,6,6,6,6,0,6 ; /2
db 6,6,6,6,6,0,6 ; /3
db 6,6,6,6,6,0,6 ; /h
db 6,1,2,3,4,6,6 ; /
db 6,6,6,6,6,6,6 ; err
end start
It should print m1
's content if there is /1
, m2
's if /2
and m3
's if /3
. 它应该打印
m1
'如果存在S含量/1
, m2
的如果/2
和m3
如果的/3
。 The problem is in this code parts: 问题出在以下代码部分:
mov dx, offset m1
mov ah, 09h
int 21h
----
mov dx, offset m2
mov ah, 09h
int 21h
----
mov dx, offset m3
mov ah, 09h
int 21h
It doesn't print anything. 它不会打印任何内容。 Even if I see in Turbo Debugger that the code is reached and there is right offset in
dx
, there is no text in stdout after int 21h
. 即使我在Turbo Debugger中看到代码已到达并且
dx
中有正确的偏移量,在int 21h
之后stdout中也没有文本。 Why? 为什么?
The multiplication at CHANGE_STATE makes no sense since DX was not initialized beforehand! 由于DX没有事先初始化,因此CHANGE_STATE处的乘法没有意义!
CHANGE_STATE:
mov ax, 7
mul dx
Hope this helps. 希望这可以帮助。
Also because you're using string primitives lodsb
you could make sure to clear the direction flag cld
. 另外,由于您使用的是字符串基元
lodsb
,因此可以确保清除方向标志cld
。
A DOS .com application stores all its code and data in only one segment and DS and ES are already initialized and equal to CS when it starts to execute. DOS .com应用程序仅将其所有代码和数据存储在一个段中,并且DS和ES已被初始化,并且在开始执行时等于CS。
... ...
For to get some commandline arguments, it is recommended for to get the segment address of the PSP before, because the current PSP is not necessarily the caller's PSP, if we start a child application from within a parent application with the exec function AX=4B00h of the int 21h for example. 为了获取一些命令行参数,建议先获取PSP的段地址,因为如果我们从具有exec函数AX = 4B00h的父应用程序中启动子应用程序,则当前PSP不一定是调用方的PSP。例如int 21h。
RBIL->inter61b.zip->INTERRUP.H RBIL-> inter61b.zip-> INTERRUP.H
--------D-2162-------------------------------
INT 21 - DOS 3.0+ - GET CURRENT PSP ADDRESS
AH = 62h
Return: BX = segment of PSP for current process
Notes: this function does not use any of the DOS-internal stacks and may
thus be called at any time, even during another INT 21h call
the current PSP is not necessarily the caller's PSP
identical to the undocumented AH=51h
SeeAlso: AH=50h,AH=51h
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.