2016-08-28 1 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 в целое число, так что вы пишете согласующие $ много байт после конца строки ('0' быть точными: кодировка ASCII от 0).

Вы также не используете начальное смещение для чего-либо. Было бы легко сделать что-то вроде lea dx, [string + bx] после получения atoi(start_offset_string) в BX.

Ваша длина отсчитывается от начала исходной строки, а не от позиции смещения. Сначала вы можете сделать смещение.

+0

Я вообще не понимаю. Я имею в виду, что вам нужно принять число, чтобы установить начало строки, которую я сделал, и я положил ее как mov bl, al. – Chouny

+0

@Chouny: посмотрите BL в отладчике в части кода прямо перед печатью строки. Я вижу эту инструкцию в вашем коде, и я все еще думаю, что мой ответ верен. Написание asm без отладчика похоже на создание робота с завязанными глазами, поэтому научитесь использовать ваш отладчик, и вы поймете этот ответ. –

+0

BX = 000A, что верно, то BX = 0102, затем 0002, затем 000A снова. Я не знаю, что произошло, но я знаю, что это не начало. – Chouny

0

Я внес некоторые небольшие изменения в ваш код, чтобы заставить его работать, эти небольшие изменения комментируются, в основном, это вопрос правильного использования указателей (указатели на начальное положение и длину), которые я заменил регистрами SI и DI :

.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 
Смежные вопросы