Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 程序集向字符串输入最多8个字符,并输出反向字符串_Assembly_Tasm_Emu8086 - Fatal编程技术网

Assembly 程序集向字符串输入最多8个字符,并输出反向字符串

Assembly 程序集向字符串输入最多8个字符,并输出反向字符串,assembly,tasm,emu8086,Assembly,Tasm,Emu8086,我有一个家庭作业问题要从用户那里得到,在一个新行的字符串中最多有8个字符,并将其反向打印 我编写了一个代码,它应该从字符串中提取每一位,并将其放入堆栈中,然后将其返回到字符串中,这样它将处于反转状态,并在新行中打印它。但当我运行文件时,它只是停留在输入上,没有给我做什么 我是装配新手,我们使用tasm1~1.4 这是我的代码: STA SEGMENT STACK DB 100H DUP (0) STA ENDS DATA SEGMENT

我有一个家庭作业问题要从用户那里得到,在一个新行的字符串中最多有8个字符,并将其反向打印

我编写了一个代码,它应该从字符串中提取每一位,并将其放入堆栈中,然后将其返回到字符串中,这样它将处于反转状态,并在新行中打印它。但当我运行文件时,它只是停留在输入上,没有给我做什么

我是装配新手,我们使用tasm1~1.4

这是我的代码:

    STA SEGMENT STACK
        DB 100H DUP (0)
    STA ENDS

    DATA SEGMENT
        MSG1 DB 'ENTER STRING (Maximum is 8) : $'
        MSG2 DB 'REVERS IS : $'
        ISTR DB 10 DUP(0)
    DATA ENDS

    CODE SEGMENT
        ASSUME CS:CODE,DS:DATA,SS:STA
    MAIN:
        MOV AX, DATA
        MOV DS, AX
        LEA DX, MSG1
        MOV AH, 09H
        INT 21H
        MOV DX, 0
    ;INPUT
        MOV DX, OFFSET ISTR
        MOV AH, 0AH
        INT 21H
        MOV SI, DX
        MOV CL, [SI+1]
        ADD SI, 2
        MOV DX, 0
        MOV BL, CL
    TOSTACK:
        MOV DX, [SI]
        PUSH DX
        INC SI
        LOOP TOSTACK
        MOV DL, 10
        MOV AH, 02H
        INT 21H
        LEA DX, MSG2
        MOV AH, 09H
        INT 21H
        MOV DX, 0
        MOV CL, BL
        MOV SI, 2
    FROMSTACK:
        POP DX
        MOV AH, 02H
        INT 21H
        INC SI
        LOOP FROMSTACK

        MOV AX, 4C00H
        INT 21H

    CODE ENDS
        END MAIN
但当我运行文件时,它只是停留在输入上

这是因为在使用DOS输入功能0Ah时,需要事先告诉DOS输入缓冲区的大小。使用类似
ISTR DB 10 DUP(0)
的定义,您实际上根本没有请求缓冲区
程序中的正确定义是

ISTR DB 9, 0, 9 DUP(0)
第一个字节指定输入缓冲区的大小。将其设置为所需的NumberOfCharacters+1。
第2个字节指定缓冲区已包含的字符数。把它归零

你可以在我的另一篇文章中找到更多关于DOS函数的信息

一旦输入工作正常,您需要修复程序TOSTACK部分的一些问题:

  • 循环
    指令依赖于整个
    CX
    寄存器,但您只填充了
    CL
    ,这是
    CX
    的低位字节。只需添加
    mov ch,0

    这显然意味着您还需要复制到
    BX
    而不是
    BL
    ,以准备FROMSTACK部分
  • 因为用户可以选择根本不提供任何字符,所以您的程序需要为这种情况做好准备。只需退出jcxz即可
  • 输入缓冲区中的每个字符都保存在一个字节中。因此,您的代码不应读取单词

摆脱慢速
循环
指令很容易:

    mov     si, offset ISTR + 1
    mov     cl, [si]     ; Characters read 0, 1, 2, ... 8
    mov     ch, 0
    jcxz    EXIT
    mov     bx, cx       ; Save count
TOSTACK:
    inc     si
    mov     dl, [si]     ; This is a byte
    push    dx           ; Don't care about high byte in DH
    dec     cx
    jnz     TOSTACK

    ...

FROMSTACK:
    pop     dx           ; Still don't care about DH
    mov     ah, 02h
    int     21h
    dec     bx
    jnz     FROMSTACK
EXIT:
    mov     ax, 4C00h
    int     21h

注释你的代码,特别是如果你想让别人帮忙的话。学习使用调试器(例如,非常用户友好的turbo调试器)单步执行代码并查看出错的地方。慢速
循环
指令使用CX(在16位模式下),而不仅仅是CL。您正在编写CL,但我看不到您零扩展到CX。IDK为什么在按下按钮之前要在
[si+1]
处存储到内存中。如果要手动存储,只需在读取输入时创建一个缓冲区和
dec
指针,然后在写入时在其上循环转发即可。(或者将整个缓冲区传递给写字符串函数。)如果您摆脱了
循环
,您可以使用
dec cl
/
jnz
。不使用
循环
的好处之一是可以选择循环条件。@PeterCordes我保留了单词extension,因为它在
dec-cx
dec-bx
中提供了更短的编码。减少了两个字节…如果您正在优化代码大小和/或一个真正的8086(其中代码获取是主要的性能瓶颈,因此在循环中节省空间是一个胜利),那么您应该使用
loop
。我认为486和更高版本的速度比较慢,但在原版8086上效果很好。谢谢,我会测试一下。我刚开始学习组装。
    mov     si, offset ISTR + 1
    mov     cl, [si]     ; Characters read 0, 1, 2, ... 8
    mov     ch, 0
    jcxz    EXIT
    mov     bx, cx       ; Save count
TOSTACK:
    inc     si
    mov     dl, [si]     ; This is a byte
    push    dx           ; Don't care about high byte in DH
    dec     cx
    jnz     TOSTACK

    ...

FROMSTACK:
    pop     dx           ; Still don't care about DH
    mov     ah, 02h
    int     21h
    dec     bx
    jnz     FROMSTACK
EXIT:
    mov     ax, 4C00h
    int     21h