2017-05-17 7 views
4

これは非常に基本的かもしれませんが、私はそれを本当に理解できません。8086組み立てに関連するトラブル

私は8255のAとBポートを使って単語を入力しています。後で

PORT_A EQU 0008h // inputs low byte 
PORT_B EQU 000Ah // inputs high byte 

コードセグメントでは、私はこれを行う部分を持っている:

MOV DX, PORT_B 
IN AL, DX 
MOV AH, AL 
MOV DX, PORT_A 
IN AL, DX 
MOV DX, AX 

私はここにいくつかの質問を持っている私のようなものを持っています。 MOV DX, PORT_Bは効果的に何をしていますか? PORT_BのアドレスをDXに保存していますか?なぜそれはIN AH, DXとして単純に書くのではなく、ALのBの上位バイトを入力し、ALをAHに移動するのですか?

ポートAとポートBのアドレスに「0008h」と「000Ah」の選択肢がありますか?私は8085アセンブリでしか作業していませんでしたが、以前は0008h(0000 0000 0000 1000b)を選択していたとしたら、000A(0000 0000 0000 1010b)を選択しませんでした。A3ビットが重なってdは0001h(... 0001b)と0002h(... 0010b)を選択し、ビットが重ならないようにします。

+0

これはかなり小さなコードサイズを与える

いくつかの点で間違って答えてください!私はあなたが他の答えのいずれかへの受け入れを変更することをお勧めします。 Fifoernikによる答えを示唆するかもしれません。それは最も完全なものです。最初に緑色のチェックマークをもう一度クリックして削除してから、正しい選択をしてください。 –

答えて

3

私はあなたが8255年代から単語のために、その後のポートと単語の上位バイトを下位バイトをフェッチされます入力する単語

を8255のAおよびBポートを使用しています8255のBポート。

ポートから何かを取得するには、まずDXレジスタにI/Oポートのアドレスを移動します。次に、in命令を使用して実際にコンテンツをフェッチします。これは、いずれかになります:

  • 我々はin eax, dx

を使用するときに我々は、これらがinのための唯一の可能な宛先ですin ax, dx

  • DWORDを使用する場合in al, dx
  • 言葉を使うバイトI/Oポートから。 (AHはオプションではありません!)

    wallykあなたが提供したコードにコメントしています。だから私はあなたがなぜ、どのようにして、すでに理解していると思います。


    私が追加したいのは、このコードを最適化できることです。上記のポートアドレスが与えられ

    PORT_A EQU 0008h // inputs low byte 
    PORT_B EQU 000Ah // inputs high byte 
    

    、単語を読んでのタスクを完了するために、より直接的な方法があります。 0000hから00FFhまでの1バイトに収まるI/Oアドレスの場合は、DXレジスタをまったく使用する必要はありません。これらのポートアドレスは、のin命令内に指定されたとすることができます。

    IN AL, PORT_B ; Fetch high byte from port B 
    MOV DH, AL  ; Becomes high byte of end result in DX 
    IN AL, PORT_A ; Fetch low byte from port A 
    MOV DL, AL  ; Becomes low byte of end result in DX 
    

    はまだ1バイト短いバージョンが(プログラミングだけで省スペースを愛する)である:私はあなたが「受け入れ」てきたことがわかり

    IN AL, PORT_B ; Fetch high byte from port B 
    MOV AH, AL  ; Store in AH for now 
    IN AL, PORT_A ; Fetch low byte from port A 
    XCHG DX, AX  ; Transfer AX to end result in DX 
    
  • +2

    優れた答え。 'XCHG'が常に' MOV'よりも小さいので簡単ではないことを明示的に指摘する価値があります。 'XCHG accum、reg'には特別な1バイトエンコーディングがあります。これは一般的な 'XCHG reg、reg'の4サイクルとは異なり、3サイクルでも実行されます。そうでなければ、「MOV reg、reg」および「XCHG reg、reg」は両方とも2バイトであり、「MOV」は2サイクルであり、「XCHG」は3-4である。そして、もちろん、XCHGは現代の*プロセッサ上での大規模な処理であるので、あなたがレトロなプログラミングをしていないときにはそのことを覚えておくことが重要です! –

    0

    MOV DX PORT_Bは、16ビットレジスタDXに定数(EQUが定数を作成する)PORT_Bの値を移動します。したがって、AXは000Ah(10進数で10)の値を取得します。 000AhはAXの8ビット部分に収まるのに十分小さいので、INは下位バイトで行われます。 AHはALの値を取得するので、PORT_Bの値はPORT_AがALに置かれている間は保持されます。

    +0

    ありがとうございました!それはIN AHという意味ですか、DXは完全に無効なオプションですか?私はALとAHを別々のレジスタとして使うことができると思ったが、おそらくIN命令と一緒にそうではないだろうか? – saremisona

    +1

    @saremisona IN AH、DXを実行できますが、PORT_Aの値を格納するために別のレジスタを使用するか、PORT_Bがメモリ内にあるときにPORT_Bを使用して演算を実行する必要があります。 – AppWriter

    +1

    また、PORT_Bのどちらかをレジスタに戻す必要があるか、または使用可能な他の算術レジスタがない場合はPORT_AをAHに置き換えて、PORT_Bを実行する必要がある間に演算を実行する必要があります(これは高価です) 。 – AppWriter

    2

    不足しているコメントは、この

    MOV DX, PORT_B  ; set up address of port B 
    IN AL, DX   ; read high byte from port B 
    MOV AH, AL   ; save result from port B as most significant byte 
    
    MOV DX, PORT_A  ; set up address of port A 
    IN AL, DX   ; read low byte from port A 
    MOV DX, AX   ; DX = 16 bit result 
    

    ようなものになるだろうなぜそれは、IN AH、DXとして代わりに簡単な書き込みの、ダウンALでその入力Bの上位バイトをし、その後、AHにALを移動しますか?

    命令のみの選択肢が

    in al, dx  ; read 8 bits 
    in ax, dx  ; read 16 bits 
    in eax, dx  ; (32 bit mode only, i.e. 80386+) read 32 bits 
    

    なので何のin ah, dxはありません。 x86命令セットと直交していますが、このような半驚くべき制限と制限があります。

    +0

    私はいつもx86が直交していると言いたいのですが、pdp11(lsi11)と言うのは直交ではないという定義のポスターの子です。確かに、x86よりもさらに悪いものがあります。時間が経つにつれて、あまり確かではありませんが、8086/88ではレジスタAx、Bx、Cx、Dxの命名にはあまり関係していません... –

    関連する問題