一道汇编语言的三级机试题!!!!求高人指教

来源:百度知道 编辑:UC知道 时间:2024/06/07 04:58:59
题目;
内存中从source 开始连续存放着21个8位有符号数(补码),其相邻两数之间差值不超过-8至7。对这种变化缓慢的数据可采用差分方法进行压缩,即一个数据不变,其后的数据取与前一数据的差值并用四位二进制补码表示,两个差值拼成一个字节,前一个差值放在高四位,后一个差值放在低四位

begin

lea si,source
lea di,result
cld
movsb; 这句指令有什么实际作用?
xor bx,bx
mov dx,n*2
compress:
lodsb
sub al,source[si-2]
xor bx,0ffh;这句话是干吗?
jz low_hex
mov cl,4
shl al,cl
mov ah,al
jmp next
low_hex:
and al,0fh ;
or al,ah;
stosb
next:
dec dx
jnz compress

关键是有一句 and al,0fh 答案说是可以求补码 但是这是怎么求的啊
补码是取反加1,但与操作能取反吗?
还有后面那句能解释下吗?

movsb ;从si地址取一个字节到di地址,然后si和di各加1;在此题中是将第一个数值放到目标地址,即题意中的“一个数据不变”

关键还是要先理解题意:
1、题意:“两个差值拼成一个字节”,本程序是在循环中完成的,这就要求在一次循环中获取一个差值(4位),并保存,下一次循环中再取得一个差值(4位),与前一个差值合并为一个字节(8位),所以两次循环的动作是有差异的,这需要一个标识来区分这个差异。这个标识是由bx来担任的。

xor bx,0ffh ;指令的作用是bx与0ff异或;在此题中,由于bx初始化为0(指令xor bx,bx),在循环中执行此指令,bx就会在0ff和00两个值之间变化,从而决定相邻两个循环的不同动作。

区分标识的方法有很多,不一定使用此方法。

2、题意:“相邻两数之间差值不超过-8至7” 表示-8~7使用4位即可,最高位是符号位。这与8位的表示法没有本质区别。而使用8位数表示-8~7,其高4位仅仅是符号位扩展。

and al,0fh ;指令的作用是将al的高4为变为0,保留低四位。由于al已经是差值(指令sub al,source[si-2]),本身就是补码,所以这不是求补码,而是将原来的8位补码变换为了4位补码。配合指令or al,ah ;ah的高4位保存上次循环的差值,低4位为0,正好与al相反;指令执行后,al就是两次差值合并的那个字节。