首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将单个字符从字符串打印到ms-dos/程序集x86-16中的标准输出。

将单个字符从字符串打印到ms-dos/程序集x86-16中的标准输出。
EN

Stack Overflow用户
提问于 2017-09-26 16:35:21
回答 3查看 5.3K关注 0票数 1

我对x86-16位编程很陌生。我很困惑如何正确地调用函数2,以便从字符串中单独读取字符。如果有人有任何想法的话,我们将不胜感激。下面的代码显示了我当前的尝试(多个尝试之一)。

代码语言:javascript
复制
    .model small
    .data
        message db "Hello, DOS Here!", 0dh, 0ah
    .code
    main proc
        mov ax, @data
        mov ds, ax
    L1:
        mov ah, 2
        mov bx, 1
        int 21h
        loop L1

        .EXIT
    main endp
    end main

我还应该使用push和pop来打印相同方法的字符串,但可以向后打印。我肯定我漏掉了一些显而易见的东西。印上几行的英镑符号我就知道了。(12月: 156;十六进制: 9C)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-30 12:21:34

使用此定义message db "Hello, DOS Here!", 0dh, 0ah,下一段代码将打印完整的消息:

代码语言:javascript
复制
mov  ah, 02h
mov  dl, message     ;Get the H character
int  21h
mov  dl, message+1   ;Get the e character
int  21h
mov  dl, message+2
int  21h
mov  dl, message+3
int  21h
mov  dl, message+4
int  21h
mov  dl, message+5
int  21h
mov  dl, message+6
int  21h
mov  dl, message+7
int  21h
mov  dl, message+8
int  21h
mov  dl, message+9
int  21h
mov  dl, message+10
int  21h
mov  dl, message+11
int  21h
mov  dl, message+12
int  21h
mov  dl, message+13
int  21h
mov  dl, message+14
int  21h
mov  dl, message+15
int  21h
mov  dl, message+16   ;Get the 0Dh carriage return
int  21h
mov  dl, message+17   ;Get the 0Ah linefeed
int  21h

很蠢,你不觉得吗?

为了使用循环并获得更多的压缩代码,我们需要:

  1. 将您的邮件地址放在地址寄存器中。你可以从SIDIBXBP中选择。我在下面的代码中选择了BX
  2. 在此地址读取一个字节。
  3. 用DOS输出字节。
  4. 在地址寄存器中增加指针。
  5. 对所有文本重复步骤2、3、4、5,方法是检查刚才输出的是否是linefeed字符。因为在你的文字里那是最后一个角色。

这个循环的一个版本:

代码语言:javascript
复制
 mov  bx, OFFSET message  ;1.
Again:
 mov  dl, [bx]            ;2.
 mov  ah, 02h             ;3.
 int  21h
 inc  bx                  ;4.
 cmp  dl, 0Ah             ;5.
 jne  Again

我还应该使用push和pop来打印相同方法的字符串,但可以向后打印。

要完成您的下一个任务,您需要在步骤2和步骤3之间放置一个push dx。然后编写一个额外的循环来显示反向字符串:

代码语言:javascript
复制
Again2:
 pop  dx
 mov  ah, 02h
 int  21h
 cmp  dl, "H"
 jne  Again2

这里的陷阱是

  • 您不应该在其他(真实)字符==>提示之前输出行提要和回车:在启动第二个循环之前执行2个pop
  • 您不能轻易地假设"H“只显示为文本的第一个字符==>提示:计数push的数目
票数 1
EN

Stack Overflow用户

发布于 2017-09-26 16:58:35

警告:我已经几十年没有这样做了,我面前也没有一个编译器能做到这一点。这看起来像一个作业,所以我不会写代码,但我会指出正确的方向。

Int 21h函数2要求您将dl设置为要输出的字符。这里不需要推送和弹出,因为DOS不使用堆栈传递参数。首先,在循环之外,您希望将寄存器指向消息的地址,类似于:MOV si, message。然后,您需要从消息中删除单个字节,并将其放入dl中。这将需要使用间接地址表示法。然后,您可以调用中断21h并写出字符。

至于循环,有几种方法可以接近它。您可以使用计数器,使用cx作为典型的寄存器,并使用LOOP语句或DECJNZ语句。或者,您可以在字符串的末尾放置一个标记,并在单击该标记时终止循环。此操作通常使用空字符。您还需要移动到字符串中的下一个字符。您可以通过添加索引或增加si寄存器的值来实现这一点。有点像INC si

尽管如此,有一种更容易避免循环的方法,但可能是作弊。看看中断21h功能9

票数 1
EN

Stack Overflow用户

发布于 2017-09-26 22:19:01

是的,使用功能9将是‘作弊’,因为它是其他练习之一(这是很容易的)。我已经修改了我的代码,并让它从开始字符开始。我只需要弄清楚如何让它继续循环,这样它就可以继续读取字符串,而不是任意停止。到目前为止,我得到的是(打印H和15E):

代码语言:javascript
复制
       .model small
    .data
        message db "Hello, DOS Here!"
    .code
    main proc
        mov ax, @data
        mov ds, ax

        mov ah, 2
        mov cx, 16
        mov dl, message
    L1: 
        int 21h
        mov dl, message + 1
        loop L1

        .EXIT
    main endp
    end main
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46431682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档