在TASM中更改字符串

时间:2016-10-08 06:49:44

标签: assembly tasm

我正在尝试使用此算法编写用于在输入字符串中搜索最小单词的程序。

我的算法:

Read character from input, but not echo
If character is space:
    current_string_length = 0;
    current_string = "";
    echo character
Else If character belong to English alphabet:
    current_string_length++;
    current_string += character;
    if current_string_length < max_string_length:
       max_string = current_string;
       max_string_length = current_length_string;
    echo character
Else If character is "\n":
    print max_string

但我是汇编中的新手,无法找到为字符串添加字符和清理字符串的方法。我怎么能这样做,或者我可能需要为这个任务选择不同的算法?

我的代码:

.model small
.stack 100h                             ; reserves 100h bytes for stack

.data
;---------------------------------------------------------------------------------- 
; Variables
maxString           db 128 dup('$') 
currentString       db 128 dup('$')
maxLength           dw 0
currentLength       dw 0
;---------------------------------------------------------------------------------- 
; Messages
helloMessage  db 10,13,'Assembly Shortest Word Finder Version 1.0 Copyright (c) 2016 RodionSoft',10,13,10,13,'Usage: enter string with length of words not more then 128 characters',10,13,10,13,10,13,10,13,'Enter string: $'
resultMessage db 10,13,"Shortest word: $"
;---------------------------------------------------------------------------------- 
; Program
.code
start :
MOV AX, @data
MOV DS, AX
;----------------------------------------------------------------------------------
; Print helloMessage
    lea dx, helloMessage                ; LEA - Load Affective Address 
    mov ah, 9                           ; print the string of the adress 
    int 21h                             ; present in DX register


;----------------------------------------------------------------------------------
; main loop
    repeat:
        ; -------------------------------------------------------------------------
        ; Read character but not echo
        mov ah, 08h                     
        int 21h
        mov ah, 0                       ; ah = 0

        cmp al, 13h                     ; if(al == enter)
        jz printResult                  ;   printResult()
        cmp al, 20h                     ; if(al == enter)   
        jz spaceinput                   ;   spaceInput()
        ; -------------------------------------------------------------------------
        cmp al, 41h                     ; if(al < 'A')
        jl badInput                     ;   badInput()
        cmp al, 7Ah                     ; if(al > 'z')
        jg badInput                     ;   badInput()
        cmp al, 5Bh                     ; if(al < '[')
        jg goodInput                    ;   goodInput()
        cmp al, 60h                     ; if(al > '`')
        jg goodInput                    ;   goodInput()
        jmp badInput                    ; else badInput()

        goodInput:
            inc currentString
            ; currentString += al


        badInput:
            jmp repeat

        spaceInput:
            mov currentLength, 0
            ;clean currentString

        endOfIteration:
            mov ah, 2                       ; echo
            int 21h
            jmp repeat                      ; loop
;---------------------------------------------------------------------------------- 
printResult:
    lea dx, secondMessage               
    mov ah, 9                           
    int 21h 
    lea dx, maxString               
    mov ah, 9                           
    int 21h 
;----------------------------------------------------------------------------------
exit:
    MOV AX, 4c00h
    INT 21h

StringComparison proc 
    push cx dx bx ax bp si di           ; save general-purpose registers    

    mov cx, maxLength                   ; cx = maxLength
    mov dx, currentLength               ; dx = currentLength
    cmp cx, dx                          ; if(currentLength > maxLength)
    jl currentBigger                    ;   currentBigger()
    jmp return                          ; else return

    currentBigger:
        ; maxString = currentString
    return:
    pop di si bp ax bx dx cx            ; restore general-purpose registers
    ret 
endp
end start

1 个答案:

答案 0 :(得分:1)

  

无法找到将字符添加到字符串并清理字符串的方法。

嗯,首先,它取决于你对什么是字符串的定义(这是汇编中的常见主题,决定如何存储数据,即哪些位/字节用于你给它们的含义和含义)

<?php require('../includes/config.inc.php'); include ('../includes/header.html'); $page_name = NAME; $page_title = 'Home'; ?> <div style="background-color:green;" class="container"> <div class="section"> <div class="row"> <div class="col s6"> <h3>Welkom</h3> </div> <div class="col s6"> <h3>Welcome</h3> </div> </div> </div> </div> <?php include ('includes/footer.html'); ?>查找示例。它由带有ASCII编码值的连续字节组成,以值resultMessage结尾,用作DOS服务的终结符。

在C / C ++中,经典字符串文字类似,但对于终结符,使用值'$'

在(旧的16b)Pascal中,第一个字节包含字符串的长度0-255,跟随&#34;长度&#34; bytes包含ASCII字母,最后没有终止符。

在Linux中,系统调用显示字符串到控制台的指针是指DOS / C定义中的字母,但是没有任何终止符,字符串的长度必须作为第二个参数提供,并且它是&#39; s程序员如何得到它。

所以,像字符串一样简单,你已经有4种不同的方法将它存储在内存中。

但是在你的情况下,你不需要只使用最终的字符串,但是建立它并改变它,所以最简单的方法可能是分配一些内存字节数组:0

要将currentString db 128 dup('$')指针放在某个寄存器中,请说end()

然后可以像这样实现常见任务:

si

所以基本上两个指针(; all callable subroutines bellow expect the register "si" ; to point beyond last character of currentString ; (except the clearString of course, which works always) appendLetterInAL: cmp si,OFFSET currentString+127 ; 127 to have one byte for '$' jae appendLetterInAL_bufferIsFull_Ignore mov [si],al ; store new letter after previous last inc si ; update "si" to point to new end() appendLetterInAL_bufferIsFull_Ignore: ret clearString: ; works also as INIT at the start of code lea si,[currentString] ret prepareStringForDOSOutput: mov BYTE PTR [si],'$' ; set terminator at end() lea dx,[currentString] ; dx = pointer to string ret getLengthOfString: ; sets cx to length of current string ; lea cx,[si - currentString] ; probably not allowed in 16b? ; other variant mov cx,si sub cx,OFFSET currentString ret copyCurrentStringToDI: ; copies current string to buffer @di ; and also terminates it in DOS way with '$' ; upon return di contains original value push bx lea bx,[currentString] push di copyCurrentStringToDI_loop: cmp bx,si ; all bytes copied jae copyCurrentStringToDI_finish mov al,[bx] inc bx mov [di],al inc di jmp copyCurrentStringToDI_loop copyCurrentStringToDI_finish: mov BYTE PTR [di],'$' ; set DOS terminator pop di ; restore di to original value pop bx ; restore also bx ret 中的当前end(),以及在编译时将字符串的开头修复为si)足以对它进行许多操作。

我希望从代码和注释中很容易理解算法和使用的数据结构。