且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我可以通过减去两个整数的汉明权获得的汉明距离?

更新时间:2023-02-27 10:46:05

我同意小丑,我试过减法方法,并给出了错误的答案。所以,我想的点点滴滴,它的工作。这里是code,我用EMU8086编译器,只需复制,粘贴和运行(与5位以下进入无符号数,它是完全注释,以使其更容易理解):

I agree with Jester, I tried the subtracting method and it gives the wrong answer. So I tried bit by bit and it worked. Here is the code, I used EMU8086 compiler, just copy, paste and run (enter unsigned numbers with 5 digits or less, it's fully commented to make it more understandable):

.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