我想对一个数组元素求和。此数组包含正数和负数。

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

最佳答案

看来您没有适本地处理整数溢出。进位标志用于无符号加法和减法,但是您希望签名加法。溢出标志用于签名加法,它总是在符号更改时设置。

编辑:先前未经测试的代码无法正常工作。这是更正的(且自包含的)代码。已通过MASM 6.11测试。

.model小
。堆栈4096

。数据
array_size dw 7
数组db -3、10,-7、14、9,-5,-100
数字数据库'0123456789abcdef'

。代码
开始:
mov ax,seg array_size; lea斧头,数据
mov ds,ax
mov,ax

mov cx,[array_size]; cx =数组大小(以字节为单位)。
lea si,array; si指向数组。

;数字以dx:bx计算。

异或
异或

add_loop:
mov al,[si];编号在al中读取。
cbw; cbw符号将al扩展为ax。
测试斧头,斧头;检查加号的符号。
js阴性

积极的: ;加数为正。
加bx,ax;添加。
adc dx,0;携带。
jmp next_number

消极的: ;加数为负。
斧头; ax = | ax |。
sub bx,ax;减去。
sbb dx,0;借。

next_number:
inc si;下一个号码。
循环adding_loop

;结果现在在dx:bx中。

mov ax,bx;结果现在在dx:ax中。

;其余代码仅用于打印。

推bx;推低字。
mov bx,dx;将大写字母复制到bx。
调用print_word_in_hexadecimal

推dx;推高单词。
mov ah,2
mov dl,':'
int 21h;打印 ':'
流行dx;弹出高位词。

流行bx;弹出低位字。
调用print_word_in_hexadecimal

mov ah,4ch
整数21h

;输入:bx:要打印的单词。
;输出: -
print_word_in_hexadecimal:
推bx
推cx
推DX
mov cl,4;算作汽油。
mov ch,4;每个单词4个半字节。
next_nibble:
rol bx,cl;向左旋转4位。
推bx;推旋转字。
和bx,0fh
mov dl,[bx +数字]
mov ah,2;打印字符。
整数21h
流行bx;弹出旋转的单词。
十二月
jnz next_nibble

流行dx
流行cx
流行bx
退回
结束开始

上面的代码对8位值进行了有符号整数加法(8位值扩展为16位值)。寄存器用法已更改,以允许将cbw用作更干净的代码。为简单起见,加负数已转换为减法。数组的硬编码偏移量(mov si, 0002h,仅当数组位于偏移量2时才有效)已被替换为lea si,array:

size_of_array dw 7
数组db -3、10,-7、14、9,-5,-100

并在代码中进行相应的更改:

lea si,size_of_array;或者,您也可以将这两行替换为:
mov cx,[si]; 1. mov cx,size_of_array(TASM/MASM语法)。
lea si,数组

以及如何检查数字是负数还是正数?好吧,您检查最高位。例如,如我的代码所示(test进行逻辑AND,但不保存结果,它仅更新标志):

测试斧头,斧头;对ax,ax进行逻辑与,但不保存结果。
js阴性;如果数字为负,则跳转。

积极的:
;这个数字是正数。
jmp my_label

消极的:
;这个数字是负数。

my_label:

关于assembly - 在程序集中添加签名号码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20302276/

10-11 16:41