如何找到字符串的长度,然后将该长度用于 运行 使用 cx 的 Loop 函数?
How do I find the length of a string and then use that length to run a Loop function using cx?
.model small
.stack 100h
.data
msg1 db "Enter your symbol line: ","$"
msg2 db "Numbers found at: ","$"
eilute db 255,0,255 dup (0) ;symbol line
nauja db 13,10,'$' ;new line
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
mov bx, -1 ; starting place -1
loopas:
lodsb ;gets the symbol
inc bx ;++
cmp al, 13 ;checks if it's the end
jz exit
cmp al, 48 ;checks if less than 0
jb loopas
cmp al, 57 ;checks if more than 9
ja loopas
mov ax, bx ;if the string ends
mov cx, 10
call printina
mov ah, 2 ;prints out new line
mov dl, 32
int 21h
jmp loopas
printina proc near ;prints the place
skloop:
xor dx, dx
div cx
push dx
cmp ax, 0
je undo
call skloop
undo:
pop dx
pdig:
add dl, 30h
cmp dl, 39h
jle pch
add al, 7
pch:
mov ah, 2
int 21h
ret ; gets back to loop
printina endp
exit:
mov ax, 4c00h ;exit
int 21h
end start
那么我如何获取字符串 "eilute" 的长度,然后使用 cx 来保存长度而不是使用循环作为每次添加 +1 直到它到达末尾,它使用字符串的长度和函数循环?
当你执行:
int 21h ;AX = 0ah
输出字符串缓冲区的第二个字符应该是字符串长度。所以你可以把它加载到 CX
您正在使用 int 21h
、ah=0Ah
,您的变量如下所示:
eilute db 255,0,255 dup (0) ;symbol line
│ │ │
│ │ └► CHARS OF THE STRING.
│ └► LENGTH OF THE STRING.
└► MAX LENGTH OF THE STRING.
以前的格式表示字符串的长度(用户输入的字符数)在第二个字节中。您只需要访问第二个字节:
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
;▼ GET CAPTURED STRING LENGTH ▼
dec si ;◄■■ SECOND BYTE OF BUFFER IS LENGTH.
mov ch, 0 ;◄■■ CLEAR CH, SO CX=CL.
mov cl, [si] ;◄■■ CX = LENGTH OF STRING.
inc si ;◄■■ RESTORE SI (POINT TO STRING AGAIN).
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
一旦你有了 CX
中的长度,你就可以做你想做的事了。
编辑:现在您的完整代码使用 CX
:
.model small
.stack 100h
.data
msg1 db "Enter your symbol line: ","$"
msg2 db "Numbers found at: ","$"
eilute db 255,0,255 dup (0) ;symbol line
nauja db 13,10,'$' ;new line
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
;▼ GET CAPTURED STRING LENGTH ▼
dec si ;◄■■ SECOND BYTE OF BUFFER IS LENGTH.
mov ch, 0 ;◄■■ CLEAR CH, SO CX=CL.
mov cl, [si] ;◄■■ CX = LENGTH OF STRING.
inc si ;◄■■ RESTORE SI (POINT TO STRING AGAIN).
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
mov bx, -1 ; starting place -1
loopas:
PUSH CX ;◄■■ PRESERVE LOOP COUNTER.
lodsb ;gets the symbol
inc bx ;++
; cmp al, 13 ;◄■■ UNNECESARY.
; jz exit ;◄■■ UNNECESARY.
cmp al, 48 ;checks if less than 0
; jb loopas
jb CONTINUE ;◄■■ NOT A DIGIT. SKIP NEXT BLOCK.
cmp al, 57 ;checks if more than 9
ja CONTINUE ;◄■■ NOT A DIGIT. SKIP NEXT BLOCK.
mov ax, bx ;if the string ends
mov cx, 10 ;◄■■ OK, CX WAS PRESERVED.
call printina
mov ah, 2 ;prints out new line
mov dl, 32
int 21h
CONTINUE: ;◄■■ JUMP HERE WHEN CHAR IS NO DIGIT.
POP CX ;◄■■ RESTORE CX.
LOOP loopas ;◄■■ CX-1. IF CX>0 JUMP.
mov ax, 4c00h ;◄■■ FINISH PROGRAM HERE.
int 21h
printina proc near ;prints the place
skloop:
xor dx, dx
div cx
push dx
cmp ax, 0
je undo
call skloop
undo:
pop dx
pdig:
add dl, 30h
cmp dl, 39h
jle pch
add al, 7
pch:
mov ah, 2
int 21h
ret ; gets back to loop
printina endp
;exit:
; mov ax, 4c00h ;◄■■ NOW FINISH
; int 21h ;◄■■ PROGRAM ABOVE.
end start
.model small
.stack 100h
.data
msg1 db "Enter your symbol line: ","$"
msg2 db "Numbers found at: ","$"
eilute db 255,0,255 dup (0) ;symbol line
nauja db 13,10,'$' ;new line
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
mov bx, -1 ; starting place -1
loopas:
lodsb ;gets the symbol
inc bx ;++
cmp al, 13 ;checks if it's the end
jz exit
cmp al, 48 ;checks if less than 0
jb loopas
cmp al, 57 ;checks if more than 9
ja loopas
mov ax, bx ;if the string ends
mov cx, 10
call printina
mov ah, 2 ;prints out new line
mov dl, 32
int 21h
jmp loopas
printina proc near ;prints the place
skloop:
xor dx, dx
div cx
push dx
cmp ax, 0
je undo
call skloop
undo:
pop dx
pdig:
add dl, 30h
cmp dl, 39h
jle pch
add al, 7
pch:
mov ah, 2
int 21h
ret ; gets back to loop
printina endp
exit:
mov ax, 4c00h ;exit
int 21h
end start
那么我如何获取字符串 "eilute" 的长度,然后使用 cx 来保存长度而不是使用循环作为每次添加 +1 直到它到达末尾,它使用字符串的长度和函数循环?
当你执行:
int 21h ;AX = 0ah
输出字符串缓冲区的第二个字符应该是字符串长度。所以你可以把它加载到 CX
您正在使用 int 21h
、ah=0Ah
,您的变量如下所示:
eilute db 255,0,255 dup (0) ;symbol line
│ │ │
│ │ └► CHARS OF THE STRING.
│ └► LENGTH OF THE STRING.
└► MAX LENGTH OF THE STRING.
以前的格式表示字符串的长度(用户输入的字符数)在第二个字节中。您只需要访问第二个字节:
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
;▼ GET CAPTURED STRING LENGTH ▼
dec si ;◄■■ SECOND BYTE OF BUFFER IS LENGTH.
mov ch, 0 ;◄■■ CLEAR CH, SO CX=CL.
mov cl, [si] ;◄■■ CX = LENGTH OF STRING.
inc si ;◄■■ RESTORE SI (POINT TO STRING AGAIN).
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
一旦你有了 CX
中的长度,你就可以做你想做的事了。
编辑:现在您的完整代码使用 CX
:
.model small
.stack 100h
.data
msg1 db "Enter your symbol line: ","$"
msg2 db "Numbers found at: ","$"
eilute db 255,0,255 dup (0) ;symbol line
nauja db 13,10,'$' ;new line
.code
start:
mov ax, @data
mov ds, ax
mov ah, 09h ;1 message
lea dx, msg1
int 21h
mov ah, 0Ah ;reads line
lea dx, eilute ;saves buff adress
mov si, dx
add si, 2
int 21h
;▼ GET CAPTURED STRING LENGTH ▼
dec si ;◄■■ SECOND BYTE OF BUFFER IS LENGTH.
mov ch, 0 ;◄■■ CLEAR CH, SO CX=CL.
mov cl, [si] ;◄■■ CX = LENGTH OF STRING.
inc si ;◄■■ RESTORE SI (POINT TO STRING AGAIN).
mov ah, 09h ;new line
lea dx, nauja
int 21h
mov ah, 09h ;prints out 2nd message
lea dx, msg2
int 21h
mov bx, -1 ; starting place -1
loopas:
PUSH CX ;◄■■ PRESERVE LOOP COUNTER.
lodsb ;gets the symbol
inc bx ;++
; cmp al, 13 ;◄■■ UNNECESARY.
; jz exit ;◄■■ UNNECESARY.
cmp al, 48 ;checks if less than 0
; jb loopas
jb CONTINUE ;◄■■ NOT A DIGIT. SKIP NEXT BLOCK.
cmp al, 57 ;checks if more than 9
ja CONTINUE ;◄■■ NOT A DIGIT. SKIP NEXT BLOCK.
mov ax, bx ;if the string ends
mov cx, 10 ;◄■■ OK, CX WAS PRESERVED.
call printina
mov ah, 2 ;prints out new line
mov dl, 32
int 21h
CONTINUE: ;◄■■ JUMP HERE WHEN CHAR IS NO DIGIT.
POP CX ;◄■■ RESTORE CX.
LOOP loopas ;◄■■ CX-1. IF CX>0 JUMP.
mov ax, 4c00h ;◄■■ FINISH PROGRAM HERE.
int 21h
printina proc near ;prints the place
skloop:
xor dx, dx
div cx
push dx
cmp ax, 0
je undo
call skloop
undo:
pop dx
pdig:
add dl, 30h
cmp dl, 39h
jle pch
add al, 7
pch:
mov ah, 2
int 21h
ret ; gets back to loop
printina endp
;exit:
; mov ax, 4c00h ;◄■■ NOW FINISH
; int 21h ;◄■■ PROGRAM ABOVE.
end start