【问题标题】:assembly switch between 2 chars in string字符串中 2 个字符之间的汇编切换
【发布时间】:2017-11-24 09:17:32
【问题描述】:

我试图在一个字符串中的 2 个字符之间翻转,所以我买了 获取指向 2 个字符的指针然后切换它们的函数。该函数适用于常规的汇编字符,但是当我将参数作为字符从字符串传递时,它开始变得疯狂并从其他地方翻转字符。 例如,我得到了这个字符串:

string db 'd', 'a', 'b', 'e', 'c', 0Dh, 0Ah, '$'

我想在“d”和“e”之间切换。 所以我这样做是为了将它们移动到函数中:

lea bx, string
lea ax, [bx] ;i use lea to get the pointer not the char
push ax

lea ax, [bx + 3]
push ax

; i know push 2 parameters.

但由于某种原因,切换后字符串变为:

string db 'e', 'c', 'b', 'd', 'a', 0Dh, 0Ah, '$'

所以它可以在 2 个字符之间进行交换,但由于某种原因,该函数对紧随其后的字符做了同样的事情:

[bx + 1][bx + 4]。 这是为什么?这是我到目前为止的代码:(print = print new line, print_ax_str 这是在 ax 中打印 ptr 字符串的函数。所有这些都来自 inc 文件)

org 100h

jmp main

string db 'd', 'a', 'b', 'e', 'c', 0Dh, 0Ah, '$'
length dw 3

main:
    xor ax, ax
    xor bx, bx
    xor dx, dx
    xor cx, cx
    xor si, si
    xor bp, bp

    lea bx, string
    mov ax, bx
    print "Before string: "
    call print_ax_str

    lea ax, [bx]
    push ax

    lea ax, [bx + 3]
    push ax

    call swap ;swap the chars.

    lea ax, string
    print "After string: "
    call print_ax_str        
    jmp end        
swap:
    push cx
    push bx
    push dx
    push ax
    push bp


    mov bp, sp

    mov ax, [bp + 12]; ax = ptr char 2

    mov cx, [bp + 14]; cx = ptr char 1

    mov bx, ax
    mov ax, [bx] ;ax = char 2

    mov bx, cx
    mov dx, [bx] ;dx = char 1
    mov [bx], ax ;char 1 = char 2 


    mov bx, [bp + 12]
    mov [bx], dx ;char 2 = char 1 
    mov ax, [bx]

    mov sp, bp
    pop bp
    pop ax
    pop dx
    pop bx
    pop cx
    retn 4


end:
    mov ah, 0
    int 16h
    ret

include prints.inc

【问题讨论】:

  • 移动字节,而不是单词。
  • 为什么swap 如此复杂?一旦加载了 arg 指针,它应该是 2 次加载和 2 次存储(相同的寄存器指向相反的指针)。哦,这是因为您将指针加载到非指针寄存器中。加载到bxsi 之类的。
  • 我将 ax 更改为 bx 并将 cx 更改为 si,但我仍然遇到 2 个问题,函数交换 4 个字符打算 2。有人吗?
  • 再看玛格丽特的评论。

标签: string assembly x86-16


【解决方案1】:
mov ax, [bx] ;ax = char 2
mov dx, [bx] ;dx = char 1
mov [bx], ax ;char 1 = char 2 
mov [bx], dx ;char 2 = char 1

您正在处理的字符串由字节组成,但是您的程序交换了单词。这就是结果关闭的原因。
作为一个快速修复写:

mov al, [bx] ;AL = char 2
mov dl, [bx] ;DL = char 1
mov [bx], al ;char 1 = char 2 
mov [bx], dl ;char 2 = char 1

如果您有兴趣编写更好的程序,请重新编写 SWAP 程序。

  • 设置BP 在推送其他寄存器之前,以便可以使用熟悉的偏移量来寻址参数,例如[bp+4] 用于第一个参数,[bp+6] 用于第二个参数。
  • 将参数直接移动到地址寄存器(BXSIDI),这样您就可以避免大量移动。

新版本:

swap:
 push bp
 mov  bp, sp

 push ax
 push dx
 push si
 push di

 mov  di, [bp + 4]  ; ptr char 2
 mov  si, [bp + 6]  ; ptr char 1

 mov  dl, [di]      ; DL = char 2
 mov  al, [si]      ; AL = char 1

 mov  [si], dl      ; char 1 = char 2 
 mov  [di], al      ; char 2 = char 1 

 pop  di
 pop  si
 pop  dx
 pop  ax

 pop  bp
 retn 4

mov ax, [bx]
mov sp, bp
pop bp
pop ax

关于这部分代码的几点说明:

  1. 你能看到mov ax,[bx] 指令后跟pop ax 指令没用吗?
  2. 您不必编写 mov sp, bp 指令,因为堆栈指针仍指向压入的寄存器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    相关资源
    最近更新 更多