我可以通过减去它们的海明重量来获得两个数字之间的汉明距离吗?
我必须在汇编中编写一个程序来导出两个十进制整数之间的汉明距离。我只是好奇是否可以简单地减去所述整数的汉明权重。或者最好只是去XOR指令路径并创建一个循环来计算它们?
答案 0 :(得分:1)
我同意Jester,我尝试了减法方法,它给出了错误的答案。所以我一点一点地尝试,它的工作原理。这是代码,我使用EMU8086编译器,只需复制,粘贴和运行(输入5位或更少的无符号数字,它已被完全注释,使其更容易理解):
.stack 100h
;------------------------------------------
.data
;------------------------------------------
msj1 db 'Enter first number: $'
str1 db 6 ;MAX NUMBER OF CHARACTERS ALLOWED (4).
db ? ;NUMBER OF CHARACTERS ENTERED BY USER.
db 6 dup (?) ;CHARACTERS ENTERED BY USER.
num1 dw ?
msj2 db 13,10,13,10,'Enter second number: $'
str2 db 6 ;MAX NUMBER OF CHARACTERS ALLOWED (4).
db ? ;NUMBER OF CHARACTERS ENTERED BY USER.
db 6 dup (?) ;CHARACTERS ENTERED BY USER.
num2 dw ?
total dw ? ;TOTAL OF DIFFERENCES BETWEEN NUM1 AND NUM2.
msj3 db 13,10,13,10,'Hamming distance: $'
str3 db 5 dup('$')
;------------------------------------------
.code
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;------------------------------------------
;DISPLAY MESSAGE.
mov ah, 9
mov dx, offset msj1
int 21h
;CAPTURE NUMBER 1 AS STRING.
mov ah, 0Ah
mov dx, offset str1
int 21h
;------------------------------------------
;DISPLAY MESSAGE.
mov ah, 9
mov dx, offset msj2
int 21h
;CAPTURE NUMBER 2 AS STRING.
mov ah, 0Ah
mov dx, offset str2
int 21h
;------------------------------------------
;CONVERT CAPTURED NUMBERS (STRINGS) TO REAL NUMBERS.
mov si, offset str1 ;PARAMETER FOR STRING2NUMBER.
call string2number
mov num1, bx ;RETURNED VALUE.
mov si, offset str2 ;PARAMETER FOR STRING2NUMBER.
call string2number
mov num2, bx ;RETURNED VALUE.
;------------------------------------------
call distance
;------------------------------------------
;DISPLAY DISTANCE.
mov ax, total
call number2string
mov ah, 9
mov dx, offset msj3
int 21h
mov ah, 9
mov dx, offset str3
int 21h
;------------------------------------------
;STOP UNTIL USER PRESS ANY KEY.
mov ah,7
int 21h
;------------------------------------------
;FINISH THE PROGRAM PROPERLY.
mov ax, 4c00h
int 21h
;------------------------------------------
;EXTRACT THE 16 BITS OF BOTH NUM1 AND NUM2,
;AND INCREASE TOTAL WHEN BITS ARE DIFFERENT.
;THE DISTANCE RETURNS IN TOTAL.
proc distance
mov cx, 16 ;COUNTER (NUMBERS HAVE 16 BITS).
while:
;EXTRACT LEAST SIGNIFICANT BIT OF NUM1 (DL)
mov dl, 0 ;ASSUME BIT WILL BE 0.
shr num1, 1 ;EXTRACT BIT TO CARRY FLAG.
jnc bit_num1
mov dl, 1 ;EXTRACTED BIT WAS 1.
bit_num1:
;EXTRACT LEAST SIGNIFICANT BIT OF NUM2 (DL)
mov dh, 0 ;ASSUME BIT WILL BE 0.
shr num2, 1 ;EXTRACT BIT TO CARRY FLAG.
jnc bit_num2
mov dh, 1 ;EXTRACTED BIT WAS 1.
bit_num2:
;GET DISTANCE.
cmp dl, dh
je bits_equal
inc total ;BITS ARE DIFFERENT.
bits_equal:
;CHECK IF PROCESS HAS FINISHED.
loop while
ret
endp
;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN AX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING.
proc number2string
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
mov si, offset str3
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
endp
;------------------------------------------
;CONVERT STRING TO NUMBER IN BX.
;SI MUST ENTER POINTING TO THE STRING.
proc string2number
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
inc si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp