2013-11-30 4 views
4

Я хочу суммировать элементы массива. Этот массив содержит положительные и отрицательные числа.Добавление подписанных номеров в сборку

array db 07, 00, -3, 10, -7, 14, 9, -5, -100 


lea ax, data 
mov ds, ax 
mov es, ax 

lea si, array 
mov cx, [si] 
mov si, 0002h 
xor ax, ax 
xor dx, dx 
Addition: 
mov bl, [si] 
cmp bl, 00h 
jl NEGATIVE 
xor bh, bh ; 
jmp NEXTT 
NEGATIVE: 
mov bh, 0ffh 
NEXTT: 
add ax, bx 
adc dx, 0 
add si, 1 
loop Addition 

Сумма (DX:AX), используя этот код = 0003 FFAE H, который является неправильным. Я думаю, что правильный ответ FFFFFFAE H.

1- Как я могу исправить эту проблему?

2- Как узнать, является ли число в регистре (например, AX) положительным или отрицательным?

Я использую Emu8086

+1

кажется мне, как данные, поступающие рассматриваются как 16-битных числа - в которых если ответ (последние 16 бит) правильный. В отношении ЦП нет разницы между «большими неподписанными положительными числами» и «отрицательными» числами. Это становится проблемой при преобразовании в тип с плавающей точкой, его распечатке и т. Д. - и в этот момент вам нужно знать, представляете ли вы целое число без знака или знака. – Floris

+0

Я буду использовать ответ, чтобы получить среднее значение этих значений, а затем распечатать среднее значение. – ammarx

+0

В этом случае вы можете просто установить DX = 0 и не волноваться о переносе. – valplo

ответ

4

кажется, что вы не обрабатываете целочисленное переполнение соответствующим образом. Флаг переноса для неподписанный сложение и вычитание, но вы хотите подписан дополнение. Флаг переполнения для подписанного добавления, он устанавливается всегда, когда знак меняется.

Редактировать: Предыдущий непроверенный код не работает должным образом. Вот исправленный (и автономный) код. Протестировано с помощью 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: 
+0

Почему вы уменьшили dx? Я запускаю ваш код, но результат был 0000 FFB8 H (DX: AX)! При добавлении 07 AX становится 0000 H. – ammarx

+0

@ammarx Извините, моя ошибка. См. Отредактированный и проверенный код выше. – nrz

+0

Большое спасибо @nrz за то, что нашли время. Но разве мы не должны проверять, есть ли переполнение при добавлении чисел. Например, когда мы добавляем 0007H, AX и DX становятся 0000H. Здесь нет переполнения, но разве мы не должны проверять? – ammarx

Смежные вопросы