首页 > 解决方案 > Intel 8086 - 反转数组或向后循环

问题描述

我一直在尝试编写一个以两种方式反转数组内容的代码。我已经使用 push 和 pop 方法正确地完成了它,但我不知道如何使用指针方式来完成它。

我要求任何可能有帮助的澄清。

.model small
.data
    tab db '12345' ,13,10,'$'
.code
main proc
    mov ax,@data
    mov ds,ax
    mov si,offset tab
    mov di,offset tab+5
    mov cx,5

    
    etiq1:  
    mov bx,[si]
    push bx
    inc si
    loop etiq1
    
    mov cx,5
    
    etiq2:
    pop dx
    mov ah,02h
    int 21h
    loop etiq2

main endp
end main

标签: assemblyreversex86-16masm

解决方案


通过堆栈反转字符串数组并使用字符串原语lodsbstosb.

当它们遇到终止字符串的回车时,push-looppop-loop都会结束。
CLD指令需要在内存中进行lodsb并向上移动。 该代码将使用 DOS.PrintString 函数 09h 一次性打印结果。stosb

  mov  ax, @data
  mov  ds, ax
  mov  di, offset tab
  mov  si, di
  mov  dx, di
  cld

etiq1:  
  lodsb
  push ax
  cmp  byte ptr [si], 13
  jne  etiq1

etiq2:
  pop  ax
  stosb
  cmp  byte ptr [di], 13
  jne  etiq2

  mov  ah, 09h        ; DOS.PrintString
  int  21h

  mov  ax, 4C00h      ; DOS.Terminate
  int  21h

使用指针反转数组的替代方法。

左边的元素使用SI指针读/写,右边的元素使用相同的指针读/写,但有适当的偏移量。
只要此偏移量保持大于零,循环就可以继续。两个地址的偏移量必须至少为 1,才能与内存中的不同字节通信。

  mov  ax, @data
  mov  ds, ax
  mov  si, offset tab
  mov  bx, 4          ; 5 elements : last element is at offset 4 from the first element
More:
  mov  al, [si]       ; Read on left side
  mov  dl, [si+bx]    ; Read on right side
  mov  [si], dl       ; Write on left side
  mov  [si+bx], al    ; Write on right side
  inc  si             ; Move to the right
  sub  bx, 2          ; Next couple of elements is 2 bytes closer to each other
  ja   More           ; Must stay above 0 to address different elements

  ; Here BX is -1, or 0 for remaining 0, or 1 element

  mov  dx, offset tab
  mov  ah, 09h        ; DOS.PrintString
  int  21h

  mov  ax, 4C00h      ; DOS.Terminate
  int  21h

接下来是一次读取和写入 2 个元素的优化。

当然,这仅在使用一定长度的数组时才重要,因此在有限的 5 字节数组中不重要!这一次,两个地址的偏移量必须至少为 3,才能与内存中的不同字通信。

  mov  ax, @data
  mov  ds, ax
  mov  si, offset tab
  mov  bx, NumberOfByteSizedElementsMinusOne
  jmp  Begin
More:
  mov  ax, [si]       ; Read pair on left side
  mov  dx, [si+bx-1]  ; Read pair on right side
  xchg al, ah
  xchg dl, dh
  mov  [si], dx       ; Write pair on left side
  mov  [si+bx-1], ax  ; Write pair on right side
  add  si, 2          ; Move to the right
  sub  bx, 4          ; Next couple of paired elements is 4 bytes closer to each other
Begin:
  cmp  bx, 3
  jge  More           ; Must stay above 2 to address different paired elements

  ; Here BX is -1, 0, 1, or 2 for remaining 0, 1, 2, or 3 elements

  cmp  bx, 0
  jle  Done
  mov  al, [si]       ; Read on left side
  mov  dl, [si+bx]    ; Read on right side
  mov  [si], dl       ; Write on left side
  mov  [si+bx], al    ; Write on right side
Done:

  mov  dx, offset tab
  mov  ah, 09h        ; DOS.PrintString
  int  21h

  mov  ax, 4C00h      ; DOS.Terminate
  int  21h

推荐阅读