2016-08-28 4 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).

시작 오프셋을 사용하는 것으로 표시되지 않습니다. 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