如何找到字符串的长度然后使用该长度来使用cx运行循环函数?

时间:2016-11-07 19:08:54

标签: string assembly dos x86-16 string-length

.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?< / p>

2 个答案:

答案 0 :(得分:1)

您使用的是int 21hah=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

答案 1 :(得分:0)

执行时:

int 21h ;AX = 0ah

输出字符串缓冲区的第二个字符串应为字符串长度。所以你可以把它加载到CX