我想总结一个数组元素。该数组包含正数和负数。
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
答案 0 :(得分:5)
您似乎没有适当地处理整数溢出。进位标志用于无符号加法和减法,但您需要已签名添加。溢出标志用于签名添加,它始终在符号更改时设置。
修改:之前未经测试的代码无法正常运行。这是更正(和自包含)的代码。用MASM 6.11测试。
.model small .stack 4096 .data array_size dw 7 array db -3, 10, -7, 14, 9, -5, -100 numbers db '0123456789abcdef' .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
更清晰的代码。为简单起见,添加负数已转换为减法。数组(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
执行逻辑AND但不保存结果,它只更新标志):
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: