Amm*_*sfi 5 x86 assembly signed addition x86-16
我想总结一个数组元素.该数组包含正数和负数.
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
Run Code Online (Sandbox Code Playgroud)
sum(DX:AX)使用此代码= 0003 FFAE H这是错误的.我认为正确的答案是FFFFFFAE H.
1-如何解决此问题?
2-如何知道寄存器中的数字(例如AX)是正数还是负数?
我用的是emu8086
您似乎没有适当地处理整数溢出.进位标志用于无符号加法和减法,但您需要签名加法.溢出标志用于签名添加,它始终在符号更改时设置.
编辑:以前未经测试的代码无法正常工作.这是更正(和自包含)的代码.用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: