1

**明確化と「よりクリーンな」コードのために編集されました。

キーボードから文字(任意の文字)を受け入れ、そのASCII値を16進数に変換してから、表示しようとしています。

基数10から16進数に変換する方法は知っていますが、間違った用語を使用していないことを確認するためです。

ASCII値として「c」を入力すると、10進値は63になります。63を16で割った値(16進数は基数16)=3.9375。後で使用するために3の商を保存します。剰余*ベース(.9375 * 16)=15.15は16進文字「F」です。

商をベースで割った値(3/16)=0.1875。商はゼロなので、これが変換の最後のステップです。剰余*ベース(.1875 * 16)= 3

それらを最後から最初に読んで(スタックについて考える場合は「最初に、最後に」)、10進数「63」(「c」のASCII)の16進値として「3F」を取得します。

これは正しいですよね?

読むのはとても簡単だと思います。キーボード(AL)から文字を取得し、BXを除数(16進数)として設定し、ALをBXで除算し、余りをスタックに格納し、後でスタックをループして表示しようとします。 。

私の問題は、乗算とINT 21H/02Hに問題があることだと思います。キャラクターを表示するために30時間を追加する必要があるかどうかわかりません...

その上、10-15を16進数でAFに変換する方法がまだわからないため、とにかくその時点(表示)にいる必要があるかどうかさえわかりません。

私は先生と話をしてみましたが、彼が私のクラスの別の生徒の群れと話し終えるのを30分待った後(彼のクラスの別のクラスからの何かについてであり、これではありません...私はかなりイライラしました)、私が得たもののほとんどは「最初からやり直す」ことでした。

「SHRとSHLの使用はどうですか?」について尋ねられたとき 指摘された通りですが、それがなくてもできるし、それらのコマンドは使えないと言われました(授業ではカバーされていません)。

私が間違っていることについて何か入力はありますか?ありがとう!

    CHAR2HEX PROC                   ; Accept a character, print it's ascii value in hex.

        MOV DX, OFFSET AskChar      ; Display prompt
        MOV AH, 09H
        INT 21H

        MOV AX, 0                   ; Clear AX

        MOV AH, 07H                 ; Get keyboard input w/ no echo (AL)
        INT 21H

        MOV BX, 16                  ; Set up the divisor (base 16)
        MOV CX, 0                   ; Initialize the counter
        MOV DX, 0                   ; Clear DX

        Divide:                         
                                    ; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
            DIV BX                  ; Divide (will be word sized).
            PUSH AX                 ; Save DX (the remainder) to stack.

            ADD CX, 1               ; Add one to counter

            MOV DX, 0               ; Clear Remainder (DX)
            CMP AX, 0               ; Compare Quotient (AX) to zero
            JNE Divide              ; If AX not 0, go to "Divide:"

        Multiply:
                                    ; Multiply remainder (from stack) by 16 to get hex value.               
            MOV DX, 0               ; Clear DX           
            POP AX                  ; Get remainder from stack into AX.

            MUL BX                  ; Multiply AX * BX.  (DX= high order bits, AX = low order bits)
            MOV DX, AX

            SUB DL, 30h             ; ADD 30h to DL 
            MOV AH, 02h             ; 02h to display AH (DL)
            INT 21H                 ; Send to DOS

            LOOP Multiply           ; If more to do, Multiply again
                                    ; LOOP subtracts 1 from CX. If non-zero, loop.
            RET
    CHAR2HEX ENDP
END START

編集済み**

やっと手に入れた!キーボードで押されたASCII文字の16進値を返すようにプログラムを取得できましたが、各余りが0から9の場合にのみ機能しました。AからFは表示されず、代わりにコロンが使用されました。セミコロンなど...

オンラインでASCII/Deicmal / Hexチャートを見て、0から9までの文字が30時間から39時間であることに気づきました。しかし、キャラクターA(16進10の場合)は40時間まで開始しません。そこで、プログラムを変更して、値が39hより大きい場合、DLに7hを追加し、それを表示するようにしました。

    CHAR2HEX PROC                   ; Accept a character, print it's ascii value in hex.

        MOV DX, OFFSET AskChar      ; Display prompt
        MOV AH, 09H
        INT 21H

        MOV AH, 07H                 ; Get keyboard input w/ no echo (AL)
        INT 21H

        MOV CL, AL                  ; Copy user input (AL) to CL
        MOV AX, 0                   ; Clear AX (get rid of HO bits)
        MOV AL, CL                  ; Copy user input back into AL

        MOV BX, 16                  ; Set up the divisor (base 16)
        MOV CX, 0                   ; Initialize the counter
        MOV DX, 0                   ; Clear DX

        Div2:                         
                                    ; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
            DIV BX                  ; Divide (will be word sized).
            PUSH DX                 ; Save DX (the remainder) to stack.

            ADD CX, 1               ; Add one to counter
            MOV DX, 0               ; Clear Remainder (DX)
            CMP AX, 0               ; Compare Quotient (AX) to zero
            JNE Div2              ; If AX not 0, go to "Div2:"

        getHex2:
            MOV DX, 0               ; Clear DX.
            POP DX                  ; Put top of stack into DX.
            ADD DL, 30h             ; Conv to character.

            CMP DL, 39h
            JG MoreHex2

        HexRet2:        

            MOV AH, 02h             ; 02h to display AH (DL)
            INT 21H                 ; Send to DOS

            LOOP getHex2            ; If more to do, getHex2 again
                                    ; LOOP subtracts 1 from CX. If non-zero, loop.
            JMP Skip2
        MoreHex2:
            ADD DL, 7h
            JMP HexRet2             ; Return to where it left off before adding 7h.
        Skip2:
            RET
    CHAR2HEX ENDP
4

2 に答える 2

1

最初にCまたは他の言語でプログラムを作成してください。言語ライブラリを使用しないでください。たとえば、printf( "%x \ n"、number)を使用して16進数を表示しないでください。ただし、数値を10で繰り返し除算して、どこかに保存してください。ここで、10で割った余り(モジュロ)は0〜9の間にあることを覚えておいてください。これをASCIIのどこかに表示するには、前述のように0x30を追加する必要があります。123は12の余り3になり、次に12は1の余り2になり、1は0の余り1になり、1 + 0x30 =0x31は2+0x30が0x32になり、3+0x30は0x33になります。

16進数も同じで、基数は10ではなく16です。vhallacが述べているように、除算演算子を使用する代わりにマスクしてシフトすることもできます。

「プログラム」をCまたは他の言語で動作させたら、基本的な操作(add、sub、divide、shift、および、orなど)を使用して低レベルで、そのコードをアセンブリ言語で書き直します。

最終的には、プログラムを他の言語で証明してasmで始める必要がなくなる可能性があります。

于 2012-04-23T21:20:31.453 に答える
1

基数10変換のロジックは適切に見えます。10で除算した余りごとに桁が表示され、最下位桁から最上位桁の順に並べられるため、取得した桁を逆にしてから印刷する必要があります。それらをスタックにプッシュし、完了したらポップすると、うまくコンパクトに反転できます。

16進数に変換する場合の操作は同じです。16で除算し、余りを取得し、逆にして、印刷します。ただし、注意すべき点がいくつかあります。16で割ると、右に4ビットシフトします。剰余はvalue AND 0fHですので、実際には算術演算は必要ありません。ビットシフトとAND動作で十分です。さらに、スタックを関与させる必要もありません。これは、最上位のニブル(4ビット)から最下位のニブルまで実行でき、計算しながら印刷できます。あなたが苦労しているように見える2番目のことは、ニブルを16進数に変換することです。単に追加するだけ30hでは不十分です。10進数には十分ですが、16進数の場合は、10から15までの数値もあります。これらを追加する必要があります41h(ASCIIの「A」)代わりにマイナス10。または、数字の「0」から「9」および「A」から「F」をテーブルに入れ、印刷するニブルの値でインデックスを付けることもできます。

また、入力から数値を読み取るルーチンを作成することもできます。改行を読み取るまで各桁を読み取り、文字を10進値に変換し、読み取った数値を保持するアキュムレータを更新します。これは、16進数と10進数の両方の出力関数に使用する必要があります。

于 2012-04-23T21:00:04.340 に答える