我的名字没有从名单上删除.汇编语言x86



scrienume label让我从键盘上读取5个字符名。lista标签在一行上显示每个列表及其索引(例如:如果我写"daria"one_answers"adria",输出是"1.daria",下一行是"2.maria")。第三个标签应该让我有可能从键盘上写一个索引号,并删除具有该索引(例如:如果我按1,名称"daria"已删除,且名称"maria"获取索引1)。

这些是输入和输出的标签。

我试着在我的程序中看到我从键盘上找到索引的位置,然后在字符串中向左移动索引大于我写的索引的所有名称。我的问题是我的名字没有从名单上删除。这将从列表中删除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

sterge的麻烦

sub al, '0'
mov al, al
mov bx, ax;
cmp bx, numes
jae invalidIndex

这样写,它总是跳转到invalidIndex。显然,您的names(列表中的名称)变量是单词大小的,您希望将来自用户的字节大小的响应扩展为一个完整的单词。mov al, al不这样做,你需要mov ah, 0(或者cbw对于这些非常小的正数)。
对于一个解决方案,考虑如下:尽管用户将使用从1开始的索引,程序应该使用0作为第一个索引,它会简化很多事情。

sub  al, '0'     ; AL=[1,9]
cbw              ; AX=[1,9]   1-based index
dec  ax          ; AX=[0,8]   0-based index
cmp  ax, numes   ; numes is [0,9]
jae  invalidIndex
mov di, si

您正在为shiftloop设置源指针和目标指针相同的指针!这样循环所做的任何功都无关紧要!

mov si, numePointer

您没有使用nummepointer我在以前的答案中定义和使用它的方式。
这是一个指针,包含名称列表末尾的地址。

elena$maria$daria$adria$
^                       ^
nume                    [numePointer]
shiftLoop:
cmp bx, 0
je updatePointer

您正在使用BX中的索引来控制迭代的次数。每次迭代只移动一个字节,而实际上你应该移动6个字节(5 + 1),所以你的复制远远不够!

sterge

解决方案假设列表中有4个名字,那么names=4:

1.elena
2.maria
3.daria
4.adria

有效的用户输入将是1234,验证码将把它转换为范围从0到3的AL。
将这个数字乘以6将得到列表中要删除的名称的偏移量。列表中需要在内存中向下移动的部分从它上面6个字节开始。如果选择最上面的项进行删除,则该部分可能为空。我下面的代码使用rep movsb指令,即使没有什么要复制,它也会工作得很好。

...
sub  al, 49      ; AL=["1","9"] 1-based input -> AL=[0,8] 0-based index
mov  ah, 6
mul  ah          ; -> AX = {0,6,12,18,24,30,36,42,48}
add  ax, offset nume
cmp  ax, numePointer
jnb  invalidIndex
mov  di, ax
lea  si, [di + 6]
mov  cx, numePointer
sub  cx, si
cld
rep movsb
mov  numePointer, di
dec  numes
jmp  bucla
...

请注意:在删除名字后,您可能会想再次使用lista。确保将numberindex重置为"1"。否则我的代码从我有一个索引问题将不能正常工作:

lista:
mov  byte ptr [numeIndex + 2], "1"
...

最新更新