开发者

Clearing out a string variable

I have writen this little experiement bootstrap that has a getline and print_string "functions". The boot stuff is taken from MikeOS tutorial but the rest I have writen myself. I compile this with NASM and run it in QEMU.

So the actual question: I've declared this variable curInpLn on line 6. What ever the user types is saved on that variable and then after enter is hit it is displayed to the user with some additional messages. What I'd like to do is to clear the contents of curInpLn each time the getline function is called but for some reason I can't manage to do that. I'm quite the beginner with Assmebly at the moment.

You can compile the code to bin format and then create a floppy image of it with: "dd status=noxfer conv=notrunc if=FILENAME.bin of=FILENAME.flp" and run it in qemu with: "qemu -fda FILENAME.flp"

BITS 16

jmp start
welcomeSTR:         db 'Welcome!',0
promptSTR:          db 'Please prompt something: ',0
responseSTR:            db 'You prompted: ',0

curInpLn:   times   80  db 0                        ;this is a variable to hold the input 'command'

curCharCnt:         dw 0

curLnNum:           dw 1


start:

    mov ax, 07C0h           ; Set up 4K stack space after this bootloader

    add ax, 288         ; (4096 + 512) / 16 bytes per paragraph

    mov ss, ax

    mov sp, 4096



    mov ax, 07C0h           ; Set data segment to where we're loaded

    mov ds, ax


    call clear_screen



    lea bx, [welcomeSTR]        ; Put string position into SI

    call print_string
    call new_line

    .waitCMD:   

        lea bx, [promptSTR]

        call print_string
        call getLine        ; Call our string-printing routine



    jmp .waitCMD



getLine:  



    cld

    mov cx, 80                  ;number of loops for loopne

    mov di, 0                   ;offset to bx

    lea bx, [curInpLn]          ;the address of our string



    .gtlLoop:

        mov ah, 00h             ;This is an bios interrupt to  

        int 16h                 ;wait for a keypress and save it to al



        cmp al, 08h             ;see if backspace was pressed

        je .gtlRemChar          ;if so, jump







        mov [bx+di], al     ;effective address of our curInpLn string 

        inc di                  ;is saved in bx, di is an offset where we will

                    ;insert our char in al



        cmp al, 0Dh             ;see if character typed is car-return (enter)

        je .gtlDone         ;if so, jump



        mov ah, 0Eh             ;bios interrupt to show the char in al

        int 10h

    .gtlCont:

        loopne .gtlLoop         ;loopne loops until cx is zero

        jmp .gtlDone



    .gtlRemChar:

        ;mov [bx][di-1], 0  ;this needs to be solved. NASM gives error on this.

        dec di

        jmp .gtlCont



    .gtlDone:

        call new_line
        lea bx, [responseSTR]

        cal开发者_Go百科l print_string

        mov [curCharCnt], di    ;save the amount of chars entered to a var


        lea bx, [curInpLn]
        call print_string
        call new_line

ret





print_string:               ; Routine: output string in SI to screen



    mov si, bx



    mov ah, 0Eh         ; int 10h 'print char' function



    .repeat:

        lodsb               ; Get character from string

        cmp al, 0

        je .done            ; If char is zero, end of string

        int 10h             ; Otherwise, print it

    jmp .repeat



.done:  


ret


new_line:

    mov ax, [curLnNum]
    inc ax
    mov [curLnNum], ax

    mov ah, 02h
    mov dl, 0
    mov dh, [curLnNum]
    int 10h

ret

clear_screen:
    push ax
    mov ax, 3
    int 10h
    pop ax
ret


times 510-($-$$) db 0       ; Pad remainder of boot sector with 0s

dw 0xAA55           ; The standard PC boot signature


I haven't written code in Assembly for 20 years (!), but it looks like you need to use the 'stosw' instruction (or 'stosb'). STOSB loads the value held in AL to the byte pointed to by ES:DI, whereas STOSSW loads the value held in AX to the word pointed to by ES:DI. The instruction automatically advances the pointer. As your variable curInpLn is 80 bytes long, you can clear it with 40 iterations of STOSW. Something like

xor ax, ax                 ; ax = 0
mov es, ds                 ; point es to our data segment
mov di, offset curInpLn    ; point di at the variable
mov cx, 40                 ; how many repetitions
rep stosw                  ; zap the variable

This method is probably the quickest method of clearing the variable as it doesn't require the CPU to retrieve any instructions from the pre-fetch queue. In fact, it allows the pre-fetch queue to fill up, thus allowing any following instructions to execute as quickly as possible.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜