サンプルのコードには2つの問題があります。
DOSがこのアドレスから実行を開始するため、ローデータをオフセット100に配置したくない場合。このため、オフセット102で始まるコードは、 "mov dx、100"命令からBAバイトを盗む "ADC AX、BA16"命令にアセンブルされ、残りの命令が誤って解釈されるため、正しく実行されません。
問題が1つもない場合、2番目の問題は、入力文字がオフセット102から始まるコードを上書きすることです(100のバッファの最初の2バイトが予約されているためです)。コードを実行させることができれば、これはおそらくあなたが望むものではありません。 ;)
これは.COMプログラムのエントリポイントであるため、オフセット100のデータは定義しません。これを処理する簡単な方法は、コードの後にデータを定義することです。ラベルを使わずにメモリの場所を直接指定しなければならないデバッグのようなものを使うときは、アセンブルされたオペランドのサイズを考慮する必要があります。
1つの方法は、アドレス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バイトのコードと環境スペースです)。ここで
EDIT 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に1バイトを予約していて、16を含む場所101には1バイトを予約しています。あなたは 'DUP '指令。 –
質問は少し不明で広すぎます。あなたはスケルトンでもう少し考えて、あなたの質問をある程度まで絞るべきです。 –
@DavidHoelzer:DOSデバッグがDUPのようなものをサポートしているとは思わない。ラベルはサポートされていません。 –