공백을 사용하여 어셈블리 코드를 분리해야 할 필요가 있습니다. 이 코드는 무언가를하고 있습니다 매우 (하나씩 다른 숫자로 나눕니다), 아직 그것은 매우 읽기가 어렵습니다. 그것은 분명히 사실이 아닙니다 : 간단한 코드는 읽기 쉽습니다! 왜 읽는 것이 어렵습니까? 당신은 당신의 상용구 코드가 실제로 나누기 연산을 수행하는 코드와 얽혀 있기 때문에, 제 눈은 그냥 유약이 나옵니다. 나는 상용구에서 중요한 비트를 찾아 낼 수 없다. 공백은 무료입니다. 두려워하지 마라. 당신의 어셈블러는 상관 없습니다. 이 같은
쓰기를 : 이제
data segment
num1 dw 0204h
num2 db 02h
quotient db ?
remainder db ?
data ends
code segment
assume cs:code, ds:data
start:
; Initialize Data Segment (DS)
mov ax, data
mov ds, ax
; Do the division and save the results
mov ax, num1
div num2
mov quotient, al
mov remainder, ah
; Terminate process
; (Note that you should also be setting AL to a result code here!)
mov ah, 4ch
int 21h
end start
code ends
, 무슨 무슨 더 명확 실질적 아닌가요? 또한, MASM/TASM을 사용하면 실수로 벗어날 수 있지만 나쁜 습관에 빠지지 마십시오. 그것은 코드를 읽을 수 없게 만들고 잘못된 결과를 얻는 또 다른 방법입니다./ 그 심볼의 오프셋 한 가지 방법은 주소를 사용하는 것입니다, 다른 방법은 내용/심볼의 값을 사용하는 것입니다 :이 코드에서 기호를 사용할 수있는 두 가지 방법이 있습니다. MASM/TASM에서 주소/오프셋을 원하면 OFFSET
키워드를 사용해야합니다. 내용/값을 사용할 때 기술적으로는 필요하지 않지만 실제로는 이어야합니다.은 역 참조가되고 있음을 나타 내기 위해 기호를 괄호로 묶습니다. 대신 즉, :
mov ax, num1
쓰기를 : 내 가슴 떨어져 그 호언 장담으로
mov ax, [num1]
은의 당신의 코드에 문제가 있는지 살펴 보자. Michael Petch는 이미 MASM/TASM이 "내가 쓰는 것이 아니라 내 뜻대로"스타일이 당신에게 어떤 호의를 베풀지 않는 또 다른 사례라고 지적했습니다. DIV
명령어와 함께 8 비트 피연산자 (num2
)를 사용했기 때문에 8 비트 나누기를 수행하고 있습니다.
AX/[num2]
AL
의 몫과 AH
의 나머지 : 즉, 실제로 일을 의미합니다. 몫이 8 비트보다 크면 AL
에 적합하지 않으며 부분이 오버플로됩니다.
해결 방법은 16 비트 나눗셈을 수행하는 것입니다.이 경우 몫은 AX
에 있고 나머지는 DX
에 배치됩니다.
는 것을 얻을 thusly 히 코드를 작성하려면 mov ax, [num1] ; AX = [num1]
xor dx, dx ; DX = 0
xor bx, bx ; BX = 0
mov bl, [num2] ; BL = [num2], BH = 0
div bx ; DX:AX/BX
mov [quotient], ax
mov [remainder], dx
(이 또한 BX
을 건드리지이기 때문에, 당신은 상단에 push bx
과 끝에 pop bx
을 수행하여 원래 값을 저장 할 수 있습니다.)
documentation for the DIV
instruction는 8 비트, 16 비트 및 32 비트 사업부가 작동하는 방법을 요약하는 편리한 테이블을 포함
Operand Size | Dividend | Divisor | Quotient | Remainder | Maximum Quotient
--------------------------------------------------------------------------------------
Word/byte | AX | r/m8 | AL | AH | 2^8 - 1
Doubleword/word | DX:AX | r/m16 | AX | DX | 2^16 - 1
Quadword/doubleword | EDX:EAX | r/m32 | EAX | EDX | 2^32 - 1
"제수"는 DIV
명령어의 유일한 피연산자입니다. "배당금"은 함축적입니다. "r/m"은 레지스터 또는 메모리 피연산자를 의미합니다.
사용중인 [DIV] (http://www.felixcloutier.com/x86/DIV.html) 명령의 형식은 다음과 같습니다. 'AX는 r/m8로 나눕니다. 결과는 AL에 저장됩니다. ← Quotient, AH ← 나머지 .' 이것은 MASM/TASM이 'num2 db 02h'정의 때문에 8 비트 메모리 피연산자 였기 때문에 조용히 num1로 간주했기 때문입니다. 이 경우 _DX_는 사용되지 않습니다 (따라서 값은 중요하지 않습니다). 틀린 것은 0x204를 2로 나눈 값이 0x102입니다. 0x102는 바이트 (바이트는 0x00에서 0xff)에 맞지 않으므로 몫이 8 바이트 레지스터 (_AL_)에 맞지 않으므로 나누기 예외 (오버플로)가 발생합니다. –
이것을 작동 시키려면 16 비트 레지스터를 0으로하고, 그 레지스터의 하위 8 비트에 mov num2를 넣고, _DX_를 0으로 설정하고, 16 비트 나눗셈을합니다 (8이 아닌). 첫 번째 코멘트의 링크에서 지시 형식은'Unsigned Divide DX : AX를 r/m16으로 나눠서 결과를 AX ← Quotient, DX ← Remainder '에 저장합니다. 분할이 완료되면 0x102는 _AX_ –