TASM汇编程序问题:填满200元素缓冲区后无法跳转至删除词输入
问题:填满200元素缓冲区后程序无法跳转至输入待删除单词环节
用TASM开发的汇编程序中,当主字符串缓冲区填满200个元素后,程序无法正常跳转到输入待删除单词的环节。以下是程序代码:
.MODEL small .STACK 100h .DATA msg1 DB "Enter string: $" msg2 DB 0Ah, 0Dh, "Enter word to delete: $" msg3 DB 0Ah, 0Dh, "Result: $" str1ml DB 200 ; maximum buffer length str1l DB 0 ; actual length of the entered string (DOS format) str1 DB 200 dup('$') ; the characters of the string, filled with '$' str2ml DB 200 str2l DB 0 str2 DB 200 dup('$') .CODE begin: ; Initialize DS and ES segments mov ax, @data mov ds, ax mov es, ax xor ax, ax ; Print message and input the main string lea dx, msg1 call strout lea dx, str1ml call strin ; Check if the buffer is full mov al, str1l cmp al, str1ml jb input_word ; if the buffer is not full, proceed to input the word ; If the buffer is full, add a terminating character mov byte ptr [str1 + 200], '$' ; add a terminating character input_word: ; Print message and input the substring (word to delete) lea dx, msg2 call strout lea dx, str2ml call strin ; Check if the buffer is full mov al, str2l cmp al, str2ml jb process_input ; if the buffer is not full, proceed to processing ; If the buffer is full, add a terminating character mov byte ptr [str2 + 199], '$' ; add a terminating character process_input: ; Prepare to search for the substring in the main string xor cx, cx mov cl, str1l ; load the length of the main string sub cl, str2l ; calculate the number of possible positions for comparison inc cl ; account for the last possible shift cld ; clear the direction flag (forward traversal) lea di, str2 ; DI points to the beginning of the substring lea si, str1 ; SI points to the beginning of the main string xor ax, ax all_string: ; Search for a match of the substring at the current position in the main string call sub_search inc si ; shift one character to the right in the main string loop all_string ; repeat the loop until CX is zero ; Move to a new line call nextstr ; Print the final result lea dx, msg3 call strout lea dx, str1 call strout _end: mov ah, 4Ch ; DOS function to terminate the program int 21h ; Procedure to move to a new line nextstr proc push dx push ax mov dl, 0Dh ; carriage return character mov ah, 02h int 21h mov dl, 0Ah ; line feed character mov ah, 02h int 21h pop ax pop dx ret nextstr endp ; Procedure to input a string (DOS function 0Ah) strin proc mov ah, 0Ah int 21h ret strin endp ; Procedure to output a string (DOS function 09h) strout proc mov ah, 09h int 21h ret strout endp ; Procedure to search for a substring in a string sub_search proc push cx push di push si mov bx, si ; save the starting address of the current comparison mov cl, str2l ; set the counter to the length of the substring repe cmpsb ; compare bytes while they are equal (SI and DI) je _eq ; if all characters are equal, jump to deletion jne _neq ; if a mismatch is found, jump to the end _eq: call delete ; call the procedure to delete the substring inc al _neq: pop si pop di pop cx ret sub_search endp ; Procedure to delete a substring delete proc push bx push di push si mov di, bx ; DI points to the beginning of the substring to delete lea si, [bx + str2l] ; SI points to the character after the substring mov cx, 200 ; maximum length of the string sub cx, bx ; calculate the remaining length of the string rep movsb ; copy the remaining part of the string pop si pop di pop bx ret delete endp end begin
问题分析
核心错误是缓冲区越界写入:
str1被定义为200 dup('$'),内存地址范围是str1到str1+199。当主字符串填满200个字符时,程序执行mov byte ptr [str1 + 200], '$',直接写入str1缓冲区外的内存区域,而该区域正好是后续变量str2ml的地址(数据段变量连续存放:str1ml→str1l→str1(200字节)→str2ml)。- 越界写入会将
str2ml的值从200覆盖为'$'(ASCII码24),导致后续输入待删除单词时,缓冲区最大长度被错误设置为24,破坏程序流程,无法正常进入输入环节。
解决方案
- 修正终止符写入位置:将主字符串满缓冲区时的终止符写入
str1的最后一个有效位置:; 原错误代码 ; mov byte ptr [str1 + 200], '$' ; 修正后 mov byte ptr [str1 + 199], '$' - 额外优化(可选):删除子串后更新
str1l的值,避免后续循环基于错误长度执行:
在sub_search的_eq分支中添加长度更新:_eq: call delete sub str1l, str2l ; 更新主字符串实际长度 inc al
内容的提问来源于stack exchange,提问作者Snow Max
相关产品推荐
相关产品推荐

