我想求一个数组元素的和。此数组包含正数和负数。
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,这是错误的。我认为正确的答案是ffffff ae H.
1-如何解决此问题
2-如何知道寄存器(例如AX)中的数字是正数还是负数
我使用emu8086
似乎没有正确处理整数溢出。进位标志用于无符号加法和减法,但您想要有符号 编辑:以前未经测试的代码无法正常工作。这是经过更正的(并且是自包含的)代码。使用MASM 6.11进行测试。 上面的代码对8位值进行有符号整数加法运算(8位值扩展为16位值)。寄存器用法已更改,允许使用 以及相应的代码变化: 如何检查一个数字是负数还是正数?好吧,你检查最高点。例如,在我的代码中(.型号小.stack 4096数据阵列大小dw 7阵列db-3、10、-7、14、9、-5、-100数字数据库"0123456789abdef"密码开始:mov ax,seg array_size;lea-ax,数据mov ds,axmov es,axmov cx,[array_size];cx=数组大小(以字节为单位)。lea-si,数组;si指向数组。;这个数字是用dx:bx计算的。xor dx,dxxor bx,bxadding_loop:mov al,[si];数字在al中读取。cbw;cbw符号将al延伸到ax。测试ax,ax;检查加数的符号。js负极阳性:;加数是正的。加bx,ax;添加adc dx,0;拿jmp next_number阴性:;加数为负数。neg-ax;ax=|ax|。sub-bx,ax;减sbb-dx,0;借下一个编号:inc-si;下一个数字。循环添加操作;现在的结果是dx:bx。mov ax,bx;现在的结果是dx:ax。;其余代码仅用于打印。推动bx;按下较低的单词。mov bx,dx;把上面的单词复制到bx。调用print_word_in_hexadecriticpush dx;推动大写字母。mov啊,2mov dl,':'int 21h;打印":"pop-dx;流行的大写字母。流行bx;弹出较低的单词。调用print_word_in_hexadecriticmov啊,4chint 21小时;输入:bx:要打印的单词。;输出:-打印_文字_十六进制:推bx推动cx推送dxmov cl,4;计算rol。mov ch,4;每个字中有4个半字节。下一个半字节:rol-bx,cl;向左旋转4位。推动bx;推送旋转的单词。和bx,0fhmov dl,[bx+numbers]mov啊,2;打印字符。int 21小时流行bx;流行旋转词。dec chjnz下一个半字节pop dxpop cx弹出bxret结束-开始
cbw
以获得更干净的代码。为简便起见,负数相加已转换为减法。阵列的硬编码偏移量(mov si, 0002h
,仅当阵列位于偏移量2时才起作用)已替换为lea si,array
:阵列dw 7的大小阵列db-3、10、-7、14、9、-5、-100
lea-si,size_of_array;或者您可以将这2行替换为:mov cx,[si];1.mov cx,size_of_array(TASM/MASM语法)。lea-si,阵列
test
执行逻辑AND,但不保存结果,它只更新标志):测试ax,ax;对ax,ax进行逻辑AND运算,但不要保存结果。js阴性;如果数字为负数,则跳转。阳性:;这个数字是正数。jmp my_label阴性:;这个数字是负数。我的标签(_L):