코드가 이며 현재으로 작성되었으므로 이후 지침에 대비하여 AL
레지스터에 원하는 값을 입력하므로 해당 명령이 필요합니다. 그 뒤에 오는 ADD
명령은 명시 적으로 AL
의 값을 사용하며 다음번 DAA
명령 (암시 적으로)도 마찬가지입니다.
그냥 우리가 같은 페이지에있어, 미래 독자의 이익을 위해,의 코드를 통과하고 주석을 할 수 있는지 확인하기 : 희망
; Set the segment register 'DS' to the constant value 'DATA'
; (indirectly via 'AX', since you can't move an immediate into a segment register).
MOV AX, DATA
MOV DS, AX
; Put the constant values 'N1' and 'N2' into the 'AX' and 'BX' registers, respectively.
MOV AX, N1
MOV BX, N2
; Add the lower 8 bits of 'BX' to the lower 8 bits of 'AX'.
ADD AL, BL
; Using the results of that last addition ('AL' and flags),
; adjust for packed binary-coded decimal arithmetic.
DAA
; Save the result (from 'AL') in 'CL' (since 'AL' is about to be clobbered).
MOV CL, AL
; Having just done the low 8 bits of 'AX' ('AL'), we are now going to do
; the high 8 bits ('AH'). But because the DAA instruction uses 'AL'
; as an implicit operand, we first need to swap 'AL' and 'AH'.
MOV AL, AH
ADD AL, BH
DAA
; Just like we saved the result of the low 8 bits in 'CL',
; save the result of the high 8 bits in 'CH'.
MOV CH, AL
; Now, the result is in 'CX' (low byte in 'CL', high byte in 'CH'),
; so store/save it into the WORD-sized variable 'BCD_SUM'.
MOV BCD_SUM, CX
; Call DOS interrupt to terminate the process.
;
; Note that there is a bug here: you should be setting the 'AL' register
; to the process's return code. You could do this explicitly with a
; 'MOV AL, ReturnCode' instruction, or you could just do
; 'MOV AX, 4C00h' to set both halves at once.
MOV AH, 4CH
INT 21H
을 이제 원래 코드의 논리를 참조 왜 그것이 어떻게 쓰여졌는지를 AX
및 BX
레지스터에 WORD 크기의 전체 값을로드 한 다음 낮은 BYTE (하위 8 비트) 및 상위 바이트에서 채워진 2 진 코드 10 진수 연산을 수행합니다. 마지막으로 BCD_SUM
에 전체 WORD 크기 값으로 결과를 저장하고 간접적으로는 CX
을 통해 스크래치 레지스터로 저장합니다.
이제 동일한 코드를 다른 방법으로 작성할 수 있지만 여전히 동일한 작업을 수행 할 수 있습니다.
ADD AH, BH ; add high bytes first
MOV AL, AH ; swap order of bytes
DAA ; adjust result of addition, now in AL
그러나, 절대적으로 같은 코드를 작성 아무런 장점이 없다 : 이것은 당신이 가질 수 있도록 당신이 질문-재정렬 지침에 제안 기본적으로 어떤이다. 그것은 단지 개인적인 선택의 문제이며, 어느 것이 더 명확하다고 생각합니다. 개인적
, I는 레지스터 설정 선호 제 (원래의 코드에서와 같이) 다음 ADD
와 백투백 DAA
을 실행. 왜? DAA
은 ADD
명령 (특히 보조 캐리 플래그, AF
)에 의해 암시 적으로 설정된 플래그에 종속되기 때문에. MOV
명령어가 플래그를 훼손하지는 않지만 은 대부분 인스트럭션을 사용하므로 ADD
과 DAA
명령어를 분리하는 습관을 가지면 찾기 힘든 버그가 발생할 위험이 있습니다.
이와 같은 명령을 재정렬하는 유일한 장점은 데이터 종속성을 완화하여 코드의 실행 속도를 높일 수 있다는 것입니다. 당신이 여전히이 세 가지 명령 사이에 끊어짐없는 종속성 체인을 가지고 있기 때문에 그것은 여기에서 일어나지 않을 것입니다.
'DAA'는'AL'과 함께 작동합니다. 결과를 거기로 옮겨야합니다. 여기처럼 - 추가하기 전에 'AH'에서'AL'으로 움직일 수 있습니다. 또는 제안 사항을 먼저 할 수도 있지만 나중에 AH를 AL로 이동해야합니다. – rkhb
고마워요. 그렇게 할 수는 있지만 여전히 daa를 사용하여 모든 것을 옮길 필요가 있습니다. – vkubre
예. 질문은 나중에 원래의 'AH'가 필요합니다.이것은 사실이 아니므로 두 솔루션이 동일합니다. – rkhb