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

解决方法

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

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

  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,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,4C00h      ; DOS.Terminate
  int  21h

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

这当然只有在处理某个长度的数组时才重要,所以不在你有限的 5 字节数组中!这一次,两个地址的偏移量必须至少为 3,才能与内存中的不同对话。

  mov  ax,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,1,or 2 for remaining 0,2,or 3 elements

  cmp  bx,0
  jle  Done
  mov  al,al    ; Write on right side
Done:

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