2016-08-28 42 views
0

我试图建立一个汇编代码,它要求一个字符串,开始打印字符串的位置以及要打印的期望长度。 假设开始和长度始终有效你能帮我确定开始和长度吗?以开始和长度汇编语言打印一个字符串

如何它应该工作:

Enter String: Hello World 
Enter Start: 3 
Enter Length: 5 
Mid-String: llo W 

所以我对如何确定字符串的开始和长度的问题。我试了好几种东西在我下面的代码所示:

.model small 
.stack 
.data 
msg1 db "Enter String:$" 
msg2 db 13,10,"Enter Start:$" 
msg3 db 13,10,"Enter Length:$" 
msg4 db 13,10,"Mid-String:$" 
nwln db 13,10 
mySample label byte 
maxlen db 10 
actlen db 0 
string db 19 dup (?) 
.code 
mov ax,@data 
mov ds,ax 
    lea dx, msg1 ;print msg1 
    mov ah,9 
    int 21h 

    lea dx,mySample ;accept string 
    mov ah,0Ah 
    int 21h 

    mov bh,0 
    mov bl,maxlen 
    mov string[bx],'$' 
    mov ah,9 
    lea dx,string ;print string accept 
    int 21h 

    lea dx, msg2 ;print msg2 and accept start 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bh,0 
    mov bl,al 

    lea dx, msg3 ;print msg3 and accept length 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov dl,al 

    ;mov maxlen,dl 
    mov bh,0 
    mov bl,maxlen 
    mov string[bx],'$' 
    lea dx,msg4  ;print msg4 
    mov ah,9 
    int 21h 
    lea dx,string ;print mid-string 
    int 21h 
mov ah,4ch 
int 21h 
END 

输出如下: output from the code above

+0

当您在调试器中单步执行此操作时,您所读取的数字实际上是否像您期望的那样寄存在寄存器中?最后一次“int 21h”之前寄存器中的值是你期望它们的值吗?如果不是,则向后查找事情的第一次停止行为,就像你期望的那样。 –

+0

Chouny,你的问题有一个新的答案,检查出来! –

回答

1

基于快速看一下过去几年的指令,在那里你实际做的偏移量和打印(假设代码的其余部分只是正确地打印和读取字符串):

您忘了将ASCII转换为整数,因此您要在字符串的末尾写入多个字节():ASCII编码的0)。

你也不会使用任何东西的起始偏移量。在将atoi(start_offset_string)转换为BX后,可以轻松地执行诸如lea dx, [string + bx]之类的操作。

您的长度从原始字符串的开头开始计数,而不是从偏移位置开始计数。你可能想先做偏移量。

+0

我不明白它我的意思是你需要接受一个数字来设置我所做的字符串的开始,我把它当作mov bl,al。 – Chouny

+0

@Chouny:在打印字符串之前,在代码部分的调试器中查看BL。我在你的代码中看到了这条指令,我仍然认为我的答案是正确的。在没有调试器的情况下编写asm就像在蒙上眼睛的时候构建一个机器人,所以要学会使用调试器,并且你会理解这个答案。 –

+0

BX = 000A,这是真的,那么BX = 0102然后再次0002然后000A。我不知道发生了什么,但我知道它没有得到开始或者如此。 – Chouny

0

我做你的代码的一些小变化,使其工作,那些小的变化评论,基本上,它是使用指针正常(指针开始位置和长度)的问题,我通过寄存器SIDI更换:

.model small 
.stack 
.data 
msg1 db "Enter String:$" 
msg2 db 13,10,"Enter Start:$" 
msg3 db 13,10,"Enter Length:$" 
msg4 db 13,10,"Mid-String:$" 
nwln db 13,10 
mySample label byte 
maxlen db 10 
actlen db 0 
string db 19 dup (?) 
.code 
mov ax,@data 
mov ds,ax 
    lea dx, msg1 ;print msg1 
    mov ah,9 
    int 21h 

    lea dx,mySample ;accept string 
    mov ah,0Ah 
    int 21h 

    mov bh,0 
    mov bl,actlen ;◄■■■ NOT MAXLEN. 
    mov string[bx],'$' 
    mov ah,9 
    lea dx,string ;print string accept 
    int 21h 

    lea dx, msg2 ;print msg2 and accept start 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bh,0 
    mov bl,al 
    mov si,bx  ;◄■■■ SAVE BX IN SI, BECAUSE WE WILL NEED 
        ;◄■■■ BX FOR SOMETHING ELSE (SI = "START"). 

    lea dx, msg3 ;print msg3 and accept length 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bl,al  ;◄■■■ REPLACE DL BY BL BECAUSE DX WILL 
        ;◄■■■ BE USED TO DISPLAY WITH INT 21H. 
    ;mov maxlen,dl 
    mov bh,0  ;◄■■■ NOW BX = "LENGTH". BUT WE WILL NEED 
    mov di,bx  ;◄■■■ BX AGAIN, SO LET'S MOVE "LENGTH" TO DI. 

    ;mov bl,maxlen 
    add di, si   ;◄■■■ CALCULATE END POSITION. 
    dec di, 1   ;◄■■■ MINUS 1 BECAUSE IT STARTS IN 0. 
    mov string[di],'$' 
    lea dx,msg4  ;print msg4 
    mov ah,9 
    int 21h 
    ;lea dx,string ;print mid-string 
    mov dx,offset string 
    add dx,si 
    int 21h 
mov ah,4ch 
int 21h 
END