请不用田间转移指令JG,JGE,JL,JLE等指令实现如下程序片段的功能
CMP AL,BL
JGE OK
XCHG AL,BL
OK: ...
------解决方案--------------------------------------------------------
4,5楼用了.if就会有条件跳转了.
2,3楼的对于平均值不为整数是有问题
改了一下,al,bl的值均不大于7Fh时是可以的:
- Assembly code
code_seg segment 'code'start:push dx;保存dx push axxor dx,dx ;下面求abs(al-bl),求差的绝对值 sub al, bl pushfcbw xor al, ah popfadc al, 0; al中为差的绝对值 xor dx, dx pop dx;下面求(al+bl)/2,求平均值 add dl,bl shr dx,1pushfadc dl,0; [(al+bl)/2]四舍五入;得出结果 mov bl,dl sub bl,al;平均值减去差的绝对值 add al,dlpopfsbb al,0;平均值加上差的绝对值 pop dx;恢复dxint 3mov ah,4chint 21hcode_seg endsend start
------解决方案--------------------------------------------------------
不先求平均值,这样就可以不担心除不尽,不知道有没有更好的算法
- Assembly code
push dx;保存dx mov ah,0 push ax;al入栈 ;下面求abs(al-bl),求差的绝对值 sub al, bl cbw xor al, ah sub al, ah;al中为差的绝对值 mov ah, 0 xor dx, dx pop dx ;求和(al+bl) add dl,bl adc dh,0 ;得出结果 mov bx,dx sub bx,ax shr bx,1 add ax,dx shr ax,1 pop dx;恢复dx
------解决方案--------------------------------------------------------
如果用jcxz指令可以有很简单的实现,不过有点投机取巧的味道。
一个不用任何转移指令的方法:
; IN: al, bl
; OUT: al = max(al,bl) bl=min(al,bl)
; 如果使用286+指令集的话,还可以省一条指令
MOV AH,BL
MOV CH,AL
MOV CL,0C
SUB CH,BL
AND CH,80
SHR CX,CL
ROL AX,CL
MOV BL,AH
------解决方案--------------------------------------------------------
多谢cnzdgs老兄捧场,10楼的方法确实是对的,
但是很不幸,也确实有一点小BUG(多谢xtdumpling):我忽略了SUB CH,BL 可能会产生溢出。
这样改一下就好了:
MOV AH,BL
MOV CH,AL
MOV CL,0CH ; omit this line for 286+ instruction set
SUB CH,BL
PUSHF
POP BX
ROR BX,CL ; use rol bx,4 for 286+ instruction set
XOR CH,BH
AND CH,80H
SHR CX,CL ; use shr cx,12 for 286+ instruction set
ROL AX,CL
MOV BL,AH