2017-11-24 37 views
2

文字列内の2つの文字の間でフリップしようとしているので、私はbuily 関数を2つの文字へのポインタを取得して切り替えます。関数は正常なassmbly文字でうまく動作しますが、文字列からcharとしてパラメータを渡すと、他の場所から文字が狂ってくることがあります。例えば は、私はこの文字列を得た:アセンブリの文字列間の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]。 なぜですか?これは、これまでの私のコードです:(プリント= INCファイルから新しい行を印刷し、print_ax_strこれは斧内部PTR文字列を印刷する機能であるすべてのこと。)

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 
+4

単語ではなくバイトを移動します。 –

+1

なぜ 'スワップ 'はとても目立たないのですか? argポインタがロードされると、2つのロードと2つのストア(反対側のポインタと同じレジスタの)が必要です。ああ、ポインタを非ポインタレジスタにロードしたからです。 'bx'や' si'などに読み込みます。 –

+0

私はaxをbxに変更し、cxをsiに変更します。まだ2つの問題があります。関数swap 4 charsは2を指しますか? –

答えて

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+4][bp+6]などのお馴染みのオフセットを使用できるように、追加のレジスタを押す前に

  • セットアップBP
  • アドレスレジスタ(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] instructiていることがわかります続いてpop ax命令が役に立たないのですか?
  2. mov sp, bp命令を書き込む必要はありません。スタックポインタがまだプッシュされたレジスタを指しているからです。