кажется, что вы не обрабатываете целочисленное переполнение соответствующим образом. Флаг переноса для неподписанный сложение и вычитание, но вы хотите подписан дополнение. Флаг переполнения для подписанного добавления, он устанавливается всегда, когда знак меняется.
Редактировать: Предыдущий непроверенный код не работает должным образом. Вот исправленный (и автономный) код. Протестировано с помощью MASM 6.11.
.model small
.stack 4096
.data
array_size dw 7
array db -3, 10, -7, 14, 9, -5, -100
numbers db 'abcdef'
.code
start:
mov ax,seg array_size ; lea ax, data
mov ds,ax
mov es,ax
mov cx,[array_size] ; cx = array size in bytes.
lea si,array ; si points to the array.
; number is computed in dx:bx.
xor dx,dx
xor bx,bx
adding_loop:
mov al,[si] ; number is read in al.
cbw ; cbw sign-extends al to ax.
test ax,ax ; check the sign of the addend.
js negative
positive: ; the addend is positive.
add bx,ax ; add.
adc dx,0 ; carry.
jmp next_number
negative: ; the addend is negative.
neg ax ; ax = |ax|.
sub bx,ax ; subtract.
sbb dx,0 ; borrow.
next_number:
inc si ; next number.
loop adding_loop
; result now in dx:bx.
mov ax,bx ; result now in dx:ax.
; the rest of the code is only for printing.
push bx ; push lower word.
mov bx,dx ; copy the upper word to bx.
call print_word_in_hexadecimal
push dx ; push upper word.
mov ah,2
mov dl,':'
int 21h ; print ':'
pop dx ; pop upper word.
pop bx ; pop lower word.
call print_word_in_hexadecimal
mov ah,4ch
int 21h
; input: bx: word to be printed.
; output: -
print_word_in_hexadecimal:
push bx
push cx
push dx
mov cl,4 ; count for rol.
mov ch,4 ; 4 nibbles in each word.
next_nibble:
rol bx,cl ; rotate 4 bits to the left.
push bx ; push rotated word.
and bx,0fh
mov dl,[bx+numbers]
mov ah,2 ; print character.
int 21h
pop bx ; pop rotated word.
dec ch
jnz next_nibble
pop dx
pop cx
pop bx
ret
end start
Приведенный выше код делает целочисленный дополнение для 8-битных значений (8-битовые значения расширяются до 16-битовых значений). Использование реестра было изменено для использования cbw
для более чистого кода. Для простоты добавление отрицательных чисел было преобразовано в вычитание. HARDCODED смещение массива (mov si, 0002h
, который работает только в случае, если массив расположен со смещением 2) был заменен lea si,array
:
size_of_array dw 7
array db -3, 10, -7, 14, 9, -5, -100
И соответствующие изменения в коде:
lea si, size_of_array ; or you can replace these 2 lines with:
mov cx, [si] ; 1. mov cx,size_of_array (TASM/MASM syntax).
lea si, array
и как проверить, является ли число отрицательным или положительным? Ну, вы проверяете самый высокий бит. Например, как в моем коде (test
делает логической И, но не сохраняет результат, он обновляет только флаги):
test ax,ax ; do logical AND for ax,ax but don't save the result.
js negative ; jumps if the number is negative.
positive:
; the number is positive.
jmp my_label
negative:
; the number is negative.
my_label:
кажется мне, как данные, поступающие рассматриваются как 16-битных числа - в которых если ответ (последние 16 бит) правильный. В отношении ЦП нет разницы между «большими неподписанными положительными числами» и «отрицательными» числами. Это становится проблемой при преобразовании в тип с плавающей точкой, его распечатке и т. Д. - и в этот момент вам нужно знать, представляете ли вы целое число без знака или знака. – Floris
Я буду использовать ответ, чтобы получить среднее значение этих значений, а затем распечатать среднее значение. – ammarx
В этом случае вы можете просто установить DX = 0 и не волноваться о переносе. – valplo