вывод на печать в сборке x86

У меня есть этот код:

INCLUDE Irvine32.inc

.data
    arry BYTE ?
    prompt1 BYTE "Enter first hex number: ",0
    prompt2 BYTE "Enter second hex number: ",0
    prompt3 BYTE "The sum is ",0
    prompt4 BYTE "The sum is out of range ",0
    prompt5 BYTE "Convert again? [y/n]: ",0
    prompt6 BYTE "First number is invalid ",0
    prompt7 BYTE "Second number is invalid ",0

.code
main PROC
    ReadInput:
        L1:
            mov edx, OFFSET prompt1
            call writeString
            mov edx, 0
            call readHex
            call Crlf
            mov ecx, eax
            jmp L3
        L2:
            mov eax, 0
            mov edx, OFFSET prompt2
            call writeString
            mov edx, 0
            call readHex
            call Crlf
            mov ebx, eax
            mov eax, 0
            jmp L4
        L3:
                cmp ecx, 0FFFFh
                JA L5
                JBE L2
        L4:
                cmp ebx, 0FFFFh
                JA  L6
                JBE addInt
        L5:
                mov edx, OFFSET prompt6
                call writeString
                            mov edx, 0
                call Crlf
                jmp L1
        L6:
                mov edx, OFFSET prompt7
                call writeString
                mov edx, 0
                call Crlf
                jmp L2

    addInt:
        clc
        mov ax, cx
        add ax, bx
        JC printError
        jmp convert

; convert hex to string
    convert:
           mov ecx, 0
           mov esi, 0
            mov si, 4
            mov cx, 10h

    convertDigit:
            dec si
            mov dx , 0
            div cx
            cmp dx, 9h
            JA  convertLetter
            add dx, 30h
            jmp printSucess

    convertLetter:      
            add dx, 37h
            jmp printSucess

    printError:
            mov edx, OFFSET prompt4
            call writeString
            call Crlf

    printSucess:
            mov arry[si], dl
            cmp ax , 0
            JNE convertDigit
            mov edx, OFFSET arry
            add dx, si
            call writeString
            call Crlf


    exit
main ENDP
END main

когда я пытался распечатать вывод, я получаю это

Введите первое шестнадцатеричное число: ff

Введите второе шестнадцатеричное число: ff

1FEer первое шестнадцатеричное число: нажмите любую клавишу, чтобы продолжить. . .

как видите, была часть prompt1, er first hex number которая застряла со значением суммы 1FE, почему это произошло

программный цикл edx зарегистрирует 3 раза: первый раз значение E, второй раз F и третий раз 1, затем он получает writeString для вывода вывода, что, по-видимому, делает программа, в это время укажите, что значение edx внезапно подскочило до 00405911, почему это произошло?

заранее благодарю за помощь


person bluebk    schedule 21.05.2013    source источник
comment
Адрес edx при копировании prompt1 toedx совпадает с адресом edx при копировании суммы в edx, что приводит к тому, что сумма добавляется и заменяет часть prompt1, как я могу изменить edx на другой адрес, поэтому он будет только вывести сумму без добавления к ней части prompt1?   -  person bluebk    schedule 21.05.2013
comment
Отсутствует код.   -  person Devolus    schedule 21.05.2013
comment
нет нет я все копирую и вставляю   -  person bluebk    schedule 21.05.2013
comment
адрес arry равен 00405910, а адрес edx при запросе ввода первого шестнадцатеричного числа равен 00405911, и когда я добавляю esi, который равен 1, к edx, адрес edx становится 00405911, что приводит к тому, что вывод отображается как 1FEer first hex number: вместо 1FE, который это то, что я хочу. Как изменить адрес edx, чтобы вывод не включал строку prompt1?   -  person bluebk    schedule 21.05.2013


Ответы (1)


Добавьте NULL-терминатор в преобразованную строку. Вы можете сделать это прямо перед циклом convertDigit:

mov byte ptr [arry+4],0


Между прочим, вам не нужно div при делении на степень двойки (например, 16). Вы можете использовать более быстрые инструкции побитового И и сдвига:

mov dx,ax
and dx,15   ; dx = ax & 15 (== ax % 16)

shr ax,4    ; ax = ax >> 4 (== ax / 16)
person Michael    schedule 21.05.2013
comment
ах, спасибо, я не могу использовать побитовые операции в этом задании - person bluebk; 21.05.2013
comment
могу я спросить, что делает mov byte ptr [arry+4],0? он читает адрес только до индекса 4? - person bluebk; 21.05.2013
comment
В вашем цикле вы начинаете с si, установленного на 4, который вы затем предварительно декрементируете перед сохранением каких-либо символов (поэтому самый высокий адрес, на который вы будете писать, равен arry+3). Итак, что делает эта новая инструкция, так это размещает NULL-терминатор сразу после последней цифры, чтобы writeString знал, где заканчивается шестнадцатеричная строка. - person Michael; 21.05.2013
comment
Вы резервируете только один байт для arry, а затем вставляете в него 4 символа. Сделайте свой буфер больше! (вероятно, 5 байт - чтобы удерживать завершающий 0) Также после ошибки печати (если это произойдет) вы проваливаетесь в printSuccess - вероятно, не то, что вы хотите... - person Frank Kotler; 21.05.2013