我在哪里可以将字符串保存在内存中以避免丢失DS的内容?

时间:2017-05-21 02:12:30

标签: assembly nasm

我有以下代码:

[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寄存器保存字符串,但我丢失了对DS寄存器的引用(因此我无法打印msg1)。我可以在哪里保存字符串?

我是汇编员的新手,我正在学习内存管理。

1 个答案:

答案 0 :(得分:1)

1)您可以在堆栈中保存几乎任何16位寄存器:

push ds
...
pop ds
ret

请注意,必须按照存储寄存器的相反顺序读取寄存器。以下示例将交换axds的值,因为ax的旧值最后存储,因此将首先读取它:

push ds
push ax
...
pop ds
pop ax

请注意,在此上下文中ret(至少在使用近内存模型时)实际上意味着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"