2016-11-07 2 views
1
.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 каждый раз, пока он не достигнет конца, он использует длину и функцию строк Loop ?Как найти длину строки, а затем использовать эту длину для запуска функции Loop с помощью cx?

ответ

1

Вы используете 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 вы можете делать то, что вы хотите сделать.

Edit: теперь ваш полный код с помощью 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 
+0

Спасибо за ответы. Итак, теперь после этого у меня есть длина строки в cx? Как написать цикл, используя его? В основном, как мне изменить «loopas:» на то, что будет использовать эту длину строки и будет делать то же самое? – Johnie78

+0

@ Johnie78, отредактировал мой ответ, используя CX. –

+0

Большое спасибо! Также комментарии очень полезны :) – Johnie78

0

При выполнении:

int 21h ;AX = 0ah

Второй символ выходного буфера строки должна быть длина строки. Таким образом, вы можете загрузить его в CX