샘플 코드에 2 개의 문제점이 있습니다.
DOS가이 주소에서 실행을 시작하기 때문에 원시 데이터를 오프셋 100에 배치하지 않으려합니다. 이 때문에 오프셋 102에서 시작하는 코드는 "mov dx, 100"명령에서 BA 바이트를 훔치는 "ADC AX, BA16"명령으로 어셈블되고 나머지 명령은 잘못 해석 될 것이기 때문에 제대로 실행되지 않습니다 .
문제 # 1이 없다면 두 번째 문제는 입력 문자가 오프셋 102에서 시작하는 코드를 덮어 쓰게된다는 것입니다 (버퍼의 처음 2 바이트가 예약되어 있으므로). 코드를 실행할 수 있다면, 이것은 아마도 당신이 원하는 것이 아닙니다. ;)
오프셋 (offset) 100의 데이터를 .COM 프로그램의 진입 점으로 정의하고 싶지는 않습니다. 이것을 처리하는 간단한 방법은 코드 뒤에 데이터를 정의하는 것입니다. 라벨을 사용하지 않고 직접 메모리 위치를 지정해야하는 곳에서 디버그와 같은 것을 사용할 때는 어셈블 된 피연산자의 크기를 고려해야합니다.
한 가지 방법은 주소 100에서 시작하여 코드를 조합하고 문자열 및 버퍼 주소에 자리 표시자를 사용하는 것입니다. 그런 다음 데이터를 정의한 후에 지침을 수정하십시오. 여기
는 수정 된 샘플입니다 :
참고 : 나는 자신을 도울 및 출력을 추가하지 못했습니다 프롬프트 난 당신에 대해 걱정한다고 생각하지 않는 문자열 입력 기능
-n test2.com
-a
0100: mov dx,100 ;100 is a placeholder for the address of output prompt
0103: mov ah,9
0105: int 21 ;output prompt
0107: mov dx,100 ;100 is a placeholder for the address of the input buffer
010A: mov ah,0a
010C: int 21 ;read user input
010E: int 20
0110: db 48 ;"H"
0111: db 65 ;"e"
0112: db 6c ;"l"
0113: db 6c ;"l"
0114: db 6f ;"o"
0115: db 3a ;":"
0116: db 20 ;<space>
0117: db 24 ;"$"/DOS strings terminated by dollar sign
0118: db 0f ;buffer member: hold 15 chars
0119: db 00 ;buffer member: character input count stored here
;the remainder of the .COM memory segment can be used to store the data
; starting at address 11A
;now that we know where our data fits, lets plug the addresses in
-a 100
0100: mov dx,110 ;address of "H" in prompt string
-a 107
0100: mov dx,118 ;address of input buffer with first two bytes reserved (see above)
;max length to read and characters read
-rcx
CX 0000
:1a
-w
Writing 001A bytes
;lets run the program
-g
Hello: <lets assume you type "cat" followed by RETURN>
Program terminated normally
;now look at the 2nd byte in the buffer for the number of characters typed
; along with the character data entered
-d 118 11e
0110 0F 03 63 61 74 0D 0D ..cat..
이전 max 입력 chars 멤버를 정의한 후 버퍼 공간 확보; 버퍼가 프로그램의 끝에 있기 때문에 버퍼 공간으로 64k 세그먼트의 나머지 부분에 액세스 할 수 있습니다. (64KB에서 코드 및 환경 공간의 0x11b 바이트를 뺀 값).
편집 2016년 9월 11일 여기
는 사용자가 입력 한 것을 출력에 대한 질문을 해결하기 위해 (설명 포함) 수정 버전 :
0100 MOV DX,0140
0103 MOV AH,09
0105 INT 21 ;output prompt
0107 MOV DX,014B
010A MOV AH,0A
010C INT 21 ;read user input
010E MOV DX,0148
0111 MOV AH,09
0113 INT 21 ;output CRLF
0115 MOV DI,[014C] ;load DI with value of characters read
0119 AND DI,00FF ; MOV above read WORD, but we only want lower byte
011D LEA DI,[DI+014D] ;point DI to end of input string
0121 MOV AL,24 ;load DOS terminator char "$" in AL
STOSB ;write it to end input string
0124 MOV DX,014D
0127 MOV AH,09
0129 INT 21 ;print the input string
012B INT 20 ;exit program
;I inserted NOPS until address 0140 so I would have room to insert code without my
; data offsets changing
0140 DB 48 ;"Hello: $" prompt begin
0141 DB 65
0142 DB 6C
0143 DB 6C
0144 DB 6F
0145 DB 3A
0146 DB 20
0147 DB 24
0148 DB 0D ;CRLF$ sequence begin
0149 DB 0A
014A DB 24
014B DB 20 ;Buffer begin (32 bytes max length)
014C DB 00
여러 가지 방법이 있습니다 CX 레지스터에 사용자 입력 수를로드하고 LOOP 명령을 사용하여 적절한 DOS 기능을 사용하여 각 문자를 인쇄하는 것과 같은 결과를 얻으십시오. 행운을 빕니다!
당신은 15 바이트를 예약하지 않았습니다. 당신은 15를 포함하는 위치 100에 바이트를 예약했습니다. 16을 포함하는 101의 바이트를 예약했습니다. 당신이'DUP '지시어. –
질문은 약간 불분명하고 너무 광범위합니다. 당신은 해골을 조금 더 생각해야하고 질문을 어느 정도 좁혀 야합니다. –
@DavidHoelzer : DOS 디버그가 DUP와 같은 것을 지원하지 않는다고 생각하지 마십시오. 레이블은 지원되지 않습니다. –