【问题标题】:I am not understanding this assemby language program for what(what will be the input or output)我不了解这个汇编语言程序的用途(输入或输出是什么)
【发布时间】:2019-09-29 00:51:58
【问题描述】:

我从我的伙伴那里得到了这个汇编程序。我的老师提供了它。不幸的是我错过了它。请有人告诉我程序编写的目的(输入/输出或目标)

.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
    MOV DX,0
    MOV AH,1
    INT 21H

    WHILE_:
    CMP AL,0DH
    JE END_WHILE
    INC DX
    INT 21H
    JMP WHILE_

    END_WHILE:
    MAIN ENDP
END MAIN

【问题讨论】:

  • 从段模型中,这是为了生成一个 .COM 可执行文件。旧的 MS-DOS 中断 21h 函数 01h 读取键盘。所以猜测CMP AL,0DH的目的。另外:如果代码是由老师提供的,那就很奇怪了,它不会循环回到中断的设置,而是重复中断并分支到其他地方。它也对DX 没有任何作用。
  • @WeatherVane - 没有调用终止程序的事实也很奇怪。
  • 回到问题:输入来自键盘,输出可能是系统错误消息。
  • 我也对此感到困惑。我不明白整个代码代表什么
  • 我认为这里的 cmets 中有足够的内容可以看出程序不完整。没有输出,也没有正确终止。

标签: assembly x86-16 microprocessors machine-language


【解决方案1】:

我已经为你评论了:

.MODEL SMALL     ; We're writing code for x86-16
.STACK 100H      ; Give us a stack of 256 bytes
.CODE            ; What follows is the code
MAIN PROC
    MOV DX,0     ; Set the counter keeping track of the length of the string to 0
    MOV AH,1     ; The DOS service we want is to read a character from standard input
    INT 21H      ; Call said DOS service

    WHILE_:
    CMP AL,0DH   ; Is the character we read a carriage return?
    JE END_WHILE ; if so jump to the end of the program
    INC DX       ; if not increment the counter keeping track of the string length
    INT 21H      ; Call the DOS service for reading the standard input again
    JMP WHILE_   ; Jump back to _WHILE

    END_WHILE:
    MAIN ENDP    ; Exit the procedure
END MAIN

作为记录,您可以更简洁、更现代的方式编写此程序集:

.model small
.stack 0x100        ; This style of hex literal is more common nowadays
.code
main proc
    mov ah, 1       ; We don't need to set this continually since nothing clobbers it
    mov dx, -1

    _while:
      inc dx
      int 0x21
      cmp al, `\r`  ; most modern assemblers will support string literals
      jne _while
    main endp
end main

【讨论】:

  • 您的回答有几个错误。 (a) 这些程序中没有任何地方调用任何 BIOS 服务! int 21h 是 DOS 服务中断。 BIOSDOS。 (b) 第二个程序循环了 65535 次,因为您将 inc dx 指令放在了 jne _while 之前! inc 仅未触及 CF。 ZF 已修改。
  • 而不是最后的dec dx,在循环之前执行mov dx, -1 可能是最有效的。 (这仅比异或归零大 1 个字节,与 dec 相同,因此这对于静态代码大小和执行指令的胜利是中性的。此外,16 位 xor dx,dx 实际上并不是现代 CPU 的依赖破坏,因为它使 EDX 的前 2 个字节保持不变;这些字节可在 16 位模式下访问。Haswell 和以后不会将 16 位部分寄存器与完整寄存器分开重命名,这与 P6 系列(PPro 到 Nehalem)不同)。跨度>
  • 因此,除代码大小和/或将标志设置为已知状态外,异或归零在 16 位代码中并不是特别好,这是一个肮脏的小秘密。 (这就是为什么最初使用它的原因,在乱序执行 x86 CPU 或部分寄存器重命名之前,CPU 设计人员值得对其进行检测和特殊情况。)和 8 位 mov reg,imm8总是 2 个字节,所以 mov cl,0 或一般不比 xor cl,cl 差的任何东西;它因微架构和周围代码而异。无论如何,您可以将mov ah,1 提升到循环之外:此 DOS 调用保留 AH。
  • @PeterCordes 刚刚排序
猜你喜欢
  • 2014-03-28
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2016-04-02
相关资源
最近更新 更多