scrienume标签让我从键盘上读取5个字符名。lista标签显示每个字符名沿着索引(例如:如果我写“daria”和“adria”,输出是“1.daria”,下一行是“2.maria”)。第三个标签应该给予我可以从键盘上写一个索引号,并删除具有该索引的字符(例如:如果我按1,名称“daria”被删除,名称“maria”获得索引1)。
These are the labels for input and output.
我试着在程序中查看从键盘写入的索引的位置,然后将索引大于我写入的索引的所有名称移到字符串的左侧。问题是我的名称没有从列表中删除。This should erase a name from the list by id
scrienume:
mov dx, offset prompt
mov ah, 09h
int 21h
mov cx, 5
mov si, numePointer
read_char:
mov ah, 01h
int 21h
mov [si], al
inc si
loop read_char
mov byte ptr [si], '$'
inc si
mov numePointer, si ; numePointer += 6
jmp bucla
lista:
mov dx, offset nume
print_names:
push dx ; (1)
mov dx, offset numeIndex
mov ah, 09h
int 21h
inc byte ptr [numeIndex + 2] ; "1" -> "2" -> "3" ...
pop dx ; (1)
mov ah, 09h
int 21h
add dx, 5 + 1
cmp dx, numePointer ; check if the current name is the last one
jb print_names
jmp bucla ; return to main loop
sterge:
; Prompt user for index of name to delete
mov dx, offset string
mov ah, 09h
int 21h
; Read index from user
mov ah, 01h
int 21h
sub al, '0'
mov al, al
mov bx, ax;
; Verify that index is valid
cmp bx, numes
jae invalidIndex
; Shift names to the left
mov cx, numes
mov si, numePointer
add si, bx
add si, bx
add si, bx
add si, bx
add si, bx
add si, 1
mov di, si
dec bx
dec numes
shiftLoop:
cmp bx, 0
je updatePointer
mov al, [si]
mov [di], al
inc si
inc di
dec bx
jmp shiftLoop
updatePointer:
mov numePointer, di
jmp bucla
invalidIndex:
; Display error message
mov dx, offset invalid
mov ah, 09h
int 21h
jmp bucla
1条答案
按热度按时间gopyfrb31#
麻烦在 * sterge *
这样写的话,它总是跳转到 * invalidIndex *。显然,您的 * numes *(列表中的名称)变量是单词大小的,您希望将来自用户的字节大小的响应扩展为一个完整的单词。
mov al, al
不这样做,您需要mov ah, 0
(或cbw
用于这些非常小的正数)。对于解决方案,请考虑以下内容:虽然用户将使用从1开始的索引,但是程序应该使用0作为第一个索引,因为这将使事情简化很多。
x一个一个一个一个x一个一个二个x
你正在为你的 * shiftloop * 设置相同的指针来指向源和目标!循环可能做的任何工作都不会有什么影响!
您没有按照我在my previous answer(s)中定义和使用 * numePointer * 的方式使用它。
这是一个指针,它包含名称列表结尾的地址。
你使用BX中的索引来控制迭代的次数,每次迭代只移动一个字节,而实际上你应该移动6个字节(5 + 1),所以你复制的还不够!
* 灭菌 * 溶液
让我们假设列表中有4个名称,因此 * numes *= 4:
有效用户输入为1、2、3和4,验证代码将其转换为AL,范围为0到3。
将这个数字乘以6将得到列表中要删除的名称的偏移量。列表中需要在内存中下移的部分将从该位置上方的6个字节开始。如果选择删除最顶端的项,则该部分可能为空。下面的代码使用
rep movsb
指令,即使没有要复制的内容,该指令也能正常工作。请注意:删除一个名字后,你可能会想再次使用 * lista *。确保你重置 * numeIndex * 为"1"。否则我的代码从I have an indexing problems将无法正常工作: