2017-05-17 5 views
4

이것은 매우 기본적인 것일 수 있지만 실제로 이해할 수는 없습니다.8086 어셈블리 관련 문제

8255의 A 및 B 포트를 사용하여 단어를 입력하고 있습니다. 내가 좋아하는 뭔가가 있습니다

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

내가 여기에 몇 가지 질문이있다 : 코드 세그먼트에서 나중에

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

을, 나는이 작업을 수행 한 부분이있다. MOV DX, PORT_B은 무엇을 효과적으로합니까? 그것은 DX에 PORT_B의 주소를 저장합니까? 왜 AL에서 B의 상위 바이트를 입력 한 다음 AL을 AH로 바꾸는 것이 간단하지 않고 IN AH, DX으로 기록합니까?

포트 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의 A와 B 포트를 사용하고

당신은 8255 년대 말 포트와의 단어에 대한 높은 바이트에 대한 다음 하위 바이트를 가져 오는됩니다 8255의 B 포트.

포트에서 무엇이든 가져 오려면 먼저 DX 레지스터에서 I/O 포트의 주소를 이동하십시오. 그런 다음 in 명령어를 사용하여 실제로 콘텐츠를 가져옵니다. 이 중 하나가 될 수 있습니다

  • 우리는 우리가 in eax, dx

를 사용할 때 우리가이가 in에 대한 유일하게 가능한 대상이다 in ax, dx

  • 더블 워드를 사용할 때 in al, dx
  • 단어를 사용하는 바이트 I/O 포트에서. (AH은 옵션이 아닙니다!)

    wallyk 당신이 제공 한 코드를 잘 설명해주었습니다. 그래서 당신은 왜 그리고 어떻게 이해했는지 생각합니다.


    내가 추가하고 싶은 것은이 코드를 최적화 할 수 있다는 점입니다. 위의 포트 주소 감안할 때

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

    는 말씀을 읽는 작업을 완료 할 수있는보다 직접적인 방법이있다. 0000h에서 00FFh까지의 단일 바이트에 맞는 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를 사용하여 연산을 수행해야합니다. – AppWriter

    +1

    또한 PORT_B를 레지스터에 다시 넣어야하거나, 다른 연산 레지스터가없는 경우 PORT_B가 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 
    

    같은 것 이유는 무엇입니까 그것을 입력 B의 높은 AL의 바이트, 다음 IN AH, DX로 대신 간단한 서면 아래로의, 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 레지스터의 이름을 지정하지 않으면 대문자가 아닌 이유가 있습니다. –