字符串

时间:2017-11-24 09:17:33

标签: string assembly x86-16

我试图在一个字符串中的2个字符之间翻转,所以我很喜欢 获取指向2个字符的指针然后切换它们的函数。该函数与常规的assmbly字符工作正常,但是当我从字符串传递参数作为字符时,它开始变得疯狂并从其他地方翻转字符。 例如,我有这个字符串:

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, '$'

所以它可以在两个字符之间进行交换,但是由于某些原因,该函数对它们后面的字符进行了相同的操作:

[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

1 个答案:

答案 0 :(得分:2)

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]等常见偏移量作为第1个参数,[bp+6]作为第2个参数使用BX参数。
  • 将参数直接移至地址寄存器(SIDIswap: 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
mov ax,[bx]

关于这部分代码的几点评论:

  1. 你能看到pop ax指令后跟的mov sp, bp指令是无用的吗?
  2. 您不必编写union all指令,因为堆栈指针仍然指向推送的寄存器。