2017-05-21 6 views
0

は、私は次のコードを持っている:DSの内容が失われないように、文字列をメモリに保存することはできますか?

[bits 16] 
org 0x100 

segment .text 
    global start 

start: 
    lea si,[msg0] 
    call print 

    call gets 

    lea si,[msg1] 
    call print 

    lea si,[ds:0] 
    call print 

    ; Termina el programa 
    mov ah,00h 
    int 21 

gets: 
    xor bx,bx 
    mov ds,bx 

gets_start: 
    ; Leemos un caracter 
    mov ah,00h 
    int 16h 

    ; Comprobamos si se presiono enter 
    cmp ah,$1C 
    je gets_end 

    ; provocamos eco 
    mov dl,al 
    mov ah,02h 
    int 21h 

    ; Almacenamos el caracter 
    mov [ds:bx],al 
    inc bx 
    jmp gets_start 

gets_end: 
    ; agregamos 0 al final de la cadena 
    xor al,al 
    inc bx 
    mov [ds:bx],al 

    ; Nueva linea 
    mov dl,0xA 
    mov ah,02h 
    int 21h 

    ret 

print: 
    ; Movemos el caracter a dl 
    mov dl,[si] 

    ; Comprobamos si el caracter es 0 
    cmp dl,0 
    je print_end 

    ; Imprimimos el caracter 
    mov ah,02h 
    int 21h 

    ; Avanzamos al siguiente caracter 
    inc si 
    jmp print 

print_end: 
    ; Termina de imprimir 
    ret 

segment .data 
    msg0 db "Ingrese su nombre: ",0 
    msg1 db "Hola ",0 

をしかしgetsに、私はDSの文字列を保存するには登録を使用して、私は(それゆえ私はmsg1を印刷することはできません)DSレジスタへの参照を失います。私はどこで文字列を保存することができますか?

私はアセンブラを初めて使用しており、メモリ管理について学んでいます。

答えて

1

1)あなたは、スタック上のほぼすべての16ビットのレジスタを保存することができます:レジスタは、彼らが保存された逆の順序で読まなければならないことを

push ds 
... 
pop ds 
ret 

注意。

push ds 
push ax 
... 
pop ds 
pop ax 

注そのret(少なくともメモリ・モデルの近くに使用する場合)は、実際に、この文脈において:axの古い値が最後に格納されたため、それが最初に読み出されるように以下の実施例はaxdsの値を交換することになります手段は、pop ipを意味する。したがって、ret命令を実行する前に、スタックに格納されたすべての値をレジスタ に読み込んでレジスタに戻す必要があります。

2)アドレスDS:BX=0:0に文字列を書き込みます。

リアルモードでは、このアドレスには割り込みテーブルが含まれています。データを書き込むことは良い考えではありません。文字列が十分に長い場合、コンピュータは間違いなくクラッシュします!それはこのようにそれを行うには、より理にかなって

... 

gets: 
    lea bx, [strgbuf] 
gets_start: 

    ... 

segment .data 
    msg0 db "Ingrese su nombre: ",0 
    msg1 db "Hola ",0 
    ; Space for the string 
    strgbuf db "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
+0

これは正常に見えるが、動的メモリは、cのように存在していますか? –

+0

@CristoferFuentesオペレーティングシステムによって異なります。 – fuz

+1

ダイナミックメモリの場合、次の3つの可能性があります。1)スタックを使用します。しかしこれは、 "ret"を使って関数から戻るときにメモリが "解放"されることを意味します。 2)オペレーティングシステムを使用してください3)より大きなメモリ領域を使用して、ダイナミックメモリを自分で処理してください。 –