assembly 我的名字不会从名单上删除,汇编语言x86

klr1opcd  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(165)

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
gopyfrb3

gopyfrb31#

麻烦在 * sterge *

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

这样写的话,它总是跳转到 * invalidIndex *。显然,您的 * numes *(列表中的名称)变量是单词大小的,您希望将来自用户的字节大小的响应扩展为一个完整的单词。mov al, al不这样做,您需要mov ah, 0(或cbw用于这些非常小的正数)。
对于解决方案,请考虑以下内容:虽然用户将使用从1开始的索引,但是程序应该使用0作为第一个索引,因为这将使事情简化很多。
x一个一个一个一个x一个一个二个x
你正在为你的 * shiftloop * 设置相同的指针来指向源和目标!循环可能做的任何工作都不会有什么影响!

mov si, numePointer

您没有按照我在my previous answer(s)中定义和使用 * numePointer * 的方式使用它。
这是一个指针,它包含名称列表结尾的地址。

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

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

* 灭菌 * 溶液

让我们假设列表中有4个名称,因此 * numes *= 4:

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

有效用户输入为1、2、3和4,验证代码将其转换为AL,范围为0到3。
将这个数字乘以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 *。确保你重置 * numeIndex * 为"1"。否则我的代码从I have an indexing problems将无法正常工作:

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

相关问题