【问题标题】:Need help combining two strings TASM需要帮助组合两个字符串 TASM
【发布时间】:2020-08-18 17:49:28
【问题描述】:

我需要帮助来组合我拥有的两个程序,但我似乎无法让它为我工作。没有得到想要的输出。

所以这是我的问题陈述:

将两个单独的字符串组合成第三个字符串并显示出来,其中第一个字符串是原样,第二个字符串是相反的。

例子:

输入:

字符串 1:“你好”

字符串 2:'.dlroW'

输出:

“你好世界。”

示例结束。

现在我们有两种方法可以解决这个问题。

第一:使用字符串函数。(首选

现在我对学习汇编语言相当陌生,所以我想使用字符串函数来学习新的东西。

第二:不使用字符串函数。

另一种方法是,如果有人可以帮助组合两个程序,一个用于连接字符串,另一个用于反转,请注意,我已经编写了两个单独的程序,它们运行良好,没有任何问题,我只是不能一起做。我的处理方式是在连接我试图反转它的字符串之前,然后继续添加第二个字符串。但我似乎无法让它工作。我已尽我所能。

    //Concatenation Code
.model tiny
.data
 msg1 db 10,13,"Enter the string 1: $"
 cat db 30 DUP('$')
 msg2 db 10,13,"Enter the string 2: $"
 msg3 db 10,13,"Concatenated string is: $"

.code
 mov ax,@data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 lea si,cat

up: mov ah,01h
    int 21h
    mov [si],al
    inc si
    cmp al,0dh
    jnz up

    lea dx,msg2
    mov ah,09h
    int 21h

    dec si

up1: mov ah,01h
     int 21h
     mov [si],al
     inc si
     cmp al,0dh
     jnz up1

     lea dx,msg3
     mov ah,09h
     int 21h

     lea dx,cat
     mov ah,09h
     int 21h

     mov ah,4ch
     int 21h
     end`

这是第 2 部分

//Reversal Code
.model tiny
.data
 msg1 db 10,13,"enter the string: $"
 string db 40 DUP('$')
 rev db 40 DUP('$')
 msg2 db 10,13,"reverse string is: $"
.code
 mov ax,@data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 mov ah,0ah
 lea dx,string
 int 21h

 lea si,string
 lea di,rev
 mov cl,[si+1]
 mov ch,00h
 add di,cx

 inc si
 inc si

 up: mov al,[si]
     mov [di],al
     inc si
     dec di
     loop up
     inc di
     mov ah,09h
     lea dx,msg2
     int 21h

     mov ah,09h
     lea dx,[di]
     int 21h

     mov ah,4ch
     int 21h
     end 

这是我通过结合这两者得出的代码。

//That's the code I tried Combining

.model tiny
.data
.model tiny
.data
 msg1 db 10,13,"Enter string1: $"
 cat db 30 DUP('$')
 msg2 db 10,13,"Enter string2: $"
 msg3 db 10,13,"Concatenated string is: $"

.code
 mov ax, @data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 lea si,cat

 up: mov ah,01h
 int 21h
 mov [si],al
 inc si
 cmp al,0dh
 jnz up
 lea dx, msg2
 mov ah,09h
 int 21h

 dec si

 up2:mov al,[si]
  mov [di],al
  inc si
  dec di
  loop up2
  inc di

 up1:mov ah,01h
 int 21h
 mov [si],al
 inc si
 cmp al,0dh
 jnz up1

 lea dx,msg3
 mov ah,09h
 int 21h

 lea dx,cat
 mov ah,09h
 int 21h

 mov ah,4ch
 int 21h
 end

My Output

您可以清楚地看到,我未能正确完成任一项任务。那么有人可以告诉我哪里出错了吗?或者教我如何使用字符串函数来做到这一点?

【问题讨论】:

  • 当您在标签up2: 处反转string1 时,您正在执行mov [di],al,但目标地址未加载到di

标签: string assembly dos x86-16 tasm


【解决方案1】:

试图进行字符串反转的up2循环来得太早了!。您已将其放置在尚未输入第二个字符串(需要反转的字符串)的位置。
如果您在程序中编写了 cmets,那么您可能自己也注意到了这一点。

这个 up2 循环使用了依赖于CX 寄存器的LOOP 指令,但是您的程序没有为CX 分配任何合适的值。

而且您的工作反转程序正在使用 2 个缓冲区。那么为什么您希望组合从单个缓冲区中工作?
定义 cat 缓冲区,以便它可以容纳两个字符串。
定义 str 缓冲区,以便它可以容纳第二个字符串。

 lea dx, msg1
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea di, cat
up:             ; Input f i r s t string
 mov ah, 01h    ; DOS.GetCharacter
 int 21h        ; -> AL
 mov [di], al
 inc di
 cmp al, 13
 jne up

 dec di         ; Throw out the 13
                ; This marks the start of the reversed string, VERY IMPORTANT
                ; So don't change DI while inputting the 2nd string

 lea dx, msg2
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea si, str
 mov dx, si
up1:            ; Input s e c o n d string
 mov ah, 01h    ; DOS.GetCharacter
 int 21h        ; -> AL
 mov [si], al
 inc si
 cmp al, 13
 jne up1

 dec si         ; Throw out the 13
 cmp si, dx
 je  done       ; Second string was empty. CAN HAPPEN!
up2:            ; Reversed copying of s e c o n d string
 dec si
 mov al, [si]
 mov [di], al
 inc di
 cmp si, dx
 ja  up2
done:
 mov ax, 0A0Dh  ; Add a proper carriage return and linefeed to the result
 mov [di], ax
 mov al, '$'    ; Terminate the result with a dollar sign
 mov [di+2], al

 lea dx, msg3
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea dx, cat
 mov ah, 09h    ; DOS.PrintString
 int 21h

第一:使用字符串函数。(首选)

up循环和up2循环中,你有没有找到下一对指令:

mov [di], al
inc di

提供

  • 方向标志 DF 是明确的,以便DI 可以递增
  • ES 段寄存器指向@data

您可以用一条STOSB 指令替换这两条指令。

这是你的程序需要做的:

.code
 mov ax, @data
 mov ds, ax
 mov es, ax
 cld

如果我们允许自己编写多个std(设置方向标志)和cld(清除方向标志)指令的愚蠢序列,我们也可以将mov al, [si]替换为lodsb。必须注意保持有效的SI 指针 (*)。

 dec si         ; (*)
up2:            ; Reversed copying of s e c o n d string
 std
 lodsb          ; Due to STD, SI will decrement
 cld
 stosb          ; Due to CLD, DI will increment
 cmp si, dx
 jae up2         ; (*)
done:
 mov ax, 0A0Dh  ; Add a proper carriage return and linefeed to the result
 stosw
 mov al, '$'    ; Terminate the result with a dollar sign
 stosb

在设置方向标志的代码中(使用std)最好以cld指令结束,这样方向标志就处于我们最期待的状态!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2019-06-20
    • 2011-09-08
    • 2014-10-04
    相关资源
    最近更新 更多