【问题标题】:printing digits in assembly 8086在汇编 8086 中打印数字
【发布时间】:2017-05-29 11:57:02
【问题描述】:

我使用我在 Internet 上找到的一些指令编写了这段代码,用于转换一些由汇编程序计算出来的数字,然后存储在寄存器或存储器中。那么我无法弄清楚如何打印包含转换后的数字的 SI。我想我需要找到一种方法回到 SI,并首先保存数据。有没有人有任何想法?

;CONVERTING DIGITS 


MOV  AX, HORIZONTAL
MOV  BX, 10         ;DIGITS ARE EXTRACTED DIVIDING BY 10.
MOV  CX, 0          ;COUNTER FOR EXTRACTED DIGITS.

CYCLE1:       
MOV  DX, 0          ;REMAINDER OF DIV WILL BE STORED HERE
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           ;TO SEE IF NUMBER IS
JNE  CYCLE1         ;NOT ZERO, LOOP BACK. 

;NOW RETRIEVING PUSHED DIGITS.

MOV  SI, OFFSET HORIZONTAL  
MOV  TMP1, CX
CYCLE2:  
POP  DX        
ADD  DL, 48    ;CONVERT DIGIT TO CHARACTER.
MOV  [SI], DL
INC  SI
LOOP CYCLE2


MOV AH,9            ; print string
MOV DX, OFFSET SI
INT 21h

【问题讨论】:

  • 我不知道mov dx, offset si 是如何编译的,什么时候应该是mov dx, offset HORIZONTAL。此外,您可能需要在调用打印服务之前使用 '$' 终止字符串 -- mov byte ptr [si], 36
  • 看起来您正在使用 HORIZONTAL 来表示数值(从 mov ax,[HORIZONTAL] 中扣除的 16 位“字”)和输出字符串(在最坏的情况下可能是 6 字节长,例如值 10000..65535),那么您是否在那里分配了足够的空间,或者您不介意覆盖内存中的以下字节?
  • 你的问题还有一个答案,看看吧!

标签: assembly x86-16 emu8086


【解决方案1】:

您的代码几乎是完美的,它只需要另一个字符串变量,在 EMU 中复制粘贴下一个代码并运行:

.model small
.stack 100h
.data

HORIZONTAL DW 61503  ;◄■■ TEST NUMBER.
RESULT     DB 6 DUP('$') ;◄■■ VARIABLE FOR THE STRING ☻.
TMP1       DW ?

.code
  mov  ax, @data
  mov  ds, ax

;CONVERTING DIGITS ( ▼ YOUR CODE ▼ ).

MOV  AX, HORIZONTAL
MOV  BX, 10         ;DIGITS ARE EXTRACTED DIVIDING BY 10.
MOV  CX, 0          ;COUNTER FOR EXTRACTED DIGITS.

CYCLE1:       
MOV  DX, 0          ;REMAINDER OF DIV WILL BE STORED HERE
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           ;TO SEE IF NUMBER IS
JNE  CYCLE1         ;NOT ZERO, LOOP BACK. 

;NOW RETRIEVING PUSHED DIGITS.

MOV  SI, OFFSET RESULT ;◄■■ VARIABLE FOR THE STRING.
MOV  TMP1, CX
CYCLE2:  
POP  DX        
ADD  DL, 48    ;CONVERT DIGIT TO CHARACTER.
MOV  [SI], DL
INC  SI
LOOP CYCLE2


MOV AH,9            ; print string
MOV DX, OFFSET RESULT ;◄■■ VARIABLE FOR THE STRING.
INT 21h

  mov  ax, 4c00h
  int  21h

【讨论】:

    【解决方案2】:

    对于将字符串打印到标准输出的 DOS 服务 09h,DS:DX 应包含指向以 $ 结尾的字符串的指针。所以你有两个任务来打印字符串:

    1. 在字符串末尾添加 $ 字符以标记其结束。
    2. DX 寄存器中放置一个指向字符串开头的指针。

    您当前的代码是错误的,因为它没有做这两件事。请记住,虽然SI 寄存器 确实 包含一个指针,但在循环完成后,它包含一个指向字符串 end 的指针,这不是你的想。您需要一个指向字符串开头的指针。幸运的是,HORIZONTAL 是字符串缓冲区开头的偏移量,所以你可以使用它! (段寄存器,DS,不需要更改。)

    所以,您的代码需要如下所示:

    ; Terminate string
    mov  BYTE PTR [si], '$'
    
    ; Print string
    mov  dx, OFFSET HORIZONTAL
    mov  ah, 09h
    int  21h
    

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      相关资源
      最近更新 更多