Как преобразовать отрицательное целое число в строку и вывести его в MASM Assembly - PullRequest
1 голос
/ 16 марта 2020

Я должен взять целые числа со знаком от пользователя, вычислить сумму введенных чисел и затем отобразить среднее. Проблема в том, что отрицательные числа не отображаются правильно, хотя я знаю, что сумма и среднее значение рассчитываются правильно.

Что мне нужно добавить в мою процедуру, чтобы учесть отрицательные числа, чтобы они отображается правильно?

.
.
.
writeVal PROC   USES eax
    LOCAL   resultString[11]:BYTE
    lea     eax, resultString
    push    eax
    push    [ebp + 8]
    call    intToStr
    lea     eax, resultString
    displayString eax ; print num
    ret     4

writeVal ENDP


intToStr PROC       USES eax ebx ecx
    LOCAL   tempChar:DWORD

    mov     eax, [ebp + 8]
    mov     ebx, 10
    mov     ecx, 0
    cld

divideByTen:
    cdq
    idiv    ebx
    push    edx
    inc     ecx
    cmp     eax, 0
    jne     divideByTen
    mov     edi, [ebp + 12] ; move into dest array
    jmp     storeChar

;store char in array

storeChar:
    pop     tempChar
    mov     al, BYTE PTR tempChar
    add     al, 48
    stosb
    loop    storeChar
    mov     al, 0
    stosb
    ret     8

intToStr ENDP
.
.
.

Ответы [ 2 ]

1 голос
/ 16 марта 2020

Вы можете просто проверить, является ли число меньше нуля, а затем использовать инструкцию neg, чтобы отменить ее и применить отрицательный знак - к буферу resultString:

Код для writeVal будет:

writeVal PROC USES eax ecx edi
    LOCAL   resultString[11]:BYTE
    lea     eax, resultString

    mov     ecx, [ebp + 8]          ; load passed number to ebx
    test    ecx, ecx                ; test number to see if it's less than zero
    jnl     non_negative            ; jump if not less to non_negative

    neg     ecx                     ; else we have a negative number so neg to make it positive
    mov     byte ptr [eax], '-'     ; set resultString[0] to '-'
    inc     eax                     ; increase resultString ptr + 1

    non_negative:

    push    eax                  ; push the resultString + 1
    push    ecx                  ; push the number
    call    intToStr             ; convert the number
    lea     eax, resultString
    printc  eax                  ; print num
    ret     4
writeVal ENDP

Скомпилируйте и запустите:

start:

    push -14286754
    call writeVal

    exit

end start

Напечатает:

-14286754
1 голос
/ 16 марта 2020

Если ввод отрицательный, запишите этот факт куда-нибудь (в регистр) и neg свой номер ввода. (например, test eax,eax / jnl, чтобы перепрыгнуть через блок, если он не меньше 0, в противном случае попадите в блок, который обрабатывает этот случай.)

Затем выполните unsigned int -> преобразование строки (используя div, а не idiv) обычным способом в буфер.

Если вы используете стратегию push / pop для обращения цифр, вы можете поместить '-' в буфер и увеличить указатель сразу. В противном случае, дождитесь конца, чтобы добавить '-', если вы храните цифры в первом порядке с наименьшей значимостью, начиная с конца буфера и уменьшая указатель (как в Как напечатать целое число на уровне сборки Программирование без printf из библиотеки c? )

Использование беззнаковых ручек углового регистра наиболее отрицательного целого числа -2147483648, битового шаблона 0x8000000. Его абсолютное значение не может быть представлено как 32-разрядное положительное целое число с дополнительным значением 2, только как 32-разрядное без знака.

...