关于装配的两个问题

时间:2015-04-13 17:49:27

标签: assembly

  1. 什么意思名称:.space 2 ^ 32 这意味着我保留的空间等于2的功率32?

  2. 当我将数字除以16时如何得到余数? 我需要将数字从Dec改为Hex,我想一想:

    • 除以16
    • 检查reaminder值是否> 9
    • 如果是,我会将值更改为{A-F}
    • 中的文字
    • 制作循环

2 个答案:

答案 0 :(得分:0)

除以2的幂的除法就像用除数减去1来计算你的数字一样简单,所以你的除数是16,你需要和15一起运算。AND运算的结果就是你的余数。

同样,如果向右移4位(2 ^ 4 = 16),你将得到同一分区的商。

要转换为十六进制,只需将上面的内容放在一个循环中,您就可以获得任何字节大小的数字的余数,一次一个半字节,然后您需要转换为ASCII十六进制表示(从右到左)。

(同样,此方法仅适用于在特定情况下为2的幂的除数。)

要将半字节从二进制(0到15)更改为ASCII十六进制数字,您还可以使用以下快捷方式,但前提是您的处理器支持DAA(十进制加法调整)操作:

            add       #$90
            daa
            adc       #$40
            daa

(具体说明当然取决于您的特定汇编语言。)

答案 1 :(得分:0)

迈克尔,这是你第二个问题的答案。你需要的是有点复杂。下一个代码完成了这项工作,它已经完全评论以帮助您理解。您没有指定哪种汇编程序,因此我使用的是8086 Intel语法。只需将其复制粘贴到EMU8086中即可运行。该程序从AX获取一个数字,将其转换为十六进制并显示它。算法是你的:连续除以16,每个余数(在0..15范围内)转换为十六进制数,然后显示。关于这个算法的有趣之处在于数字是以相反的顺序提取的,所以有必要再次反转它们以使它们成为直线,这就是为什么连续的余数存储在堆栈中(因为堆栈中的东西得到了在开出时反转):

.stack 100h
.data
hex_char db ?,'$' ;HEX CHARACTERS TO DISPLAY.
.code      
;INITIALIZE DATA SEGMENT.
  mov  ax,@data
  mov  ds,ax

  mov  ax, 30922  ;ANY NUMBER TO CONVERT.
  call number2hex                

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h     

;-------------------------------------
;THIS PROC CONVERTS AX INTO HEX AND DISPLAYS RESULT.
;ALGORITHM : DIVIDE AX BY 16, CONVERT REMAINDER INTO 
;HEX (0..9,A..F), REPEAT UNTIL QUOTIENT == 0. DIGITS 
;EXTRACTED ARE BEEN PRESERVED IN STACK BECAUSE THEY
;HAVE TO BE DISPLAYED IN REVERSE ORDER.
;REMAINDER IS ALWAYS LESS THAN 16.

proc number2hex               

;PHASE 1 : EXTRACT ALL DIGITS INSERTING THEM IN STACK.

  mov  bx, 16  ;DIVIDE NUMBER BY 16. 
  mov  cx, 0   ;COUNTER FOR DIGITS. NECESSARY LATER.
extracting:         
  mov  dx, 0  ;CLEAR DX BECAUSE DIV DIVIDES DX:AX / BX.
  div  bx     ;DX:AX / BX. RESULT: AX=QUOTIENT, DX=REMAINDER.
  cmp  ax, 0  ;IF ( QUOTIENT==0 ) PROCESS IS OVER.
  je   last_digit
  push dx  ;PRESERVE DIGIT FOR LATER CONVERSION.
  inc  cx  ;COUNT THIS DIGIT.
  jmp  extracting  ;REPEAT PROCESS.

;WHEN PROCESS IS OVER REMAINDER STILL HOLDS LAST DIGIT.
last_digit:
  push dx  ;PRESERVE DIGIT FOR LATER CONVERSION.
  inc  cx  ;COUNT THIS DIGIT.

;PHASE 2 : EXTRACT DIGITS FROM STACK IN REVERSE ORDER
;CONVERTING THEM TO HEX AND DISPLAY THEM.       

converting:
  pop  dx  ;GET DIGIT FROM STACK.
  call convert_hex  ;CONVERT DL INTO HEX.
  call display_hex  ;DISPLAY DL.
  loop converting   ;CX-1. IF ( CX > 0 ) GOTO CONVERTING.

  ret
endp  

;-------------------------------------
;GETS THE VALUE IN "DL" AND REPLACES IT
;BY THE CORRESPONDING HEX VALUE.

proc convert_hex
  cmp  dl, 10
  jb   its_a_number  ;IF ( DL < 10 ) IT'S A NUMBER.
;IF NO JUMP IT'S A LETTER.
  add  dl, 55  ;CONVERT 10..15 TO 'A'..'F'.
  jmp  end_convert  ;SKIP "ITS_A_NUMBER".
its_a_number: 
  add  dl, 48  ;CONVERT 0..9 TO '0'..'9'.
end_convert:
  ret
endp

;-------------------------------------
;GET HEX DIGIT IN "DL", TRANSFER VALUE
;TO "HEX_CHAR", DISPLAY "HEX_CHAR".

proc display_hex
  mov  hex_char, dl
  mov  dx, offset hex_char
  mov  ah, 9
  int  21h
  ret
endp

注意有时使用DX,有时使用DL。这是因为堆栈需要两个字节(DX),但余数总是8位长(DL),因为除以16会抛出小于16(0..15)的余数。