어셈블리에서 구문은 특정 어셈블러에 따라 다릅니다. Emu8086은 주로 MASM 방언을 따르고 있습니다.이 방언은 규칙이 매우 편하며 다른 여러 가지를 허용합니다 options (with same output).
일부 고급 프로그래밍 언어에 익숙하다면 혼동스럽고 구문이 왜 돌로 설정되어 있지 않은지, 그리고이 혼란과 함께 살 수있는 이유가있을 것입니다.
그러나 asm 프로그래머의 경우에는 어셈블리에서 연산자와 다른 값으로 런타임 표현식을 작성하지 않기 때문에 거의 문제가되지 않습니다. 소스의 명령어는 보통 정확한 인수와 함께 CPU 명령어 중 하나에 매핑되는 1 : 1입니다 및 CPU에 존재하는 특정 명령의 옵션. 그것은 여러 가지 명령 옵 코드에 사용되는 단일 니모닉 "MOV는"있는 그대로
86에 MOV
instruction
은 조금 혼란 그 자체이지만, 귀하의 예제에서 두 명령이 사용됩니다
MOV r/m8,imm8
를 오피
C6
와 바이트 값을 저장하고,
MOV r/m16,imm16
단어 값을 저장하기위한 op 코드
C7
. 그리고 모든 경우에
r/m
부분은 컴파일시 계산되는 절대 오프셋에 의한 메모리 참조입니다. 메모리에
; machine code | disassembled instruction from machine code
C606001041 mov byte [0x1000],0x41
스토어 바이트 값 0x41
('A'
) 주소 ds:0x1000
에서 :
msg
메모리 주소 0x1000
에 대한 기호가 그렇다면, 귀하의 질문에 그 라인은 컴파일합니다. C6 06
은 MOV [offset16],imm8
명령 opcode이고 00 10
바이트는 0x1000
offset16 그 자체 (리틀 엔디안)이며, 마지막으로 41
은입니다. 세그먼트 ds
은 기본적으로 전체 실제 메모리 주소를 계산하는 데 사용됩니다. 그 이유는 해당 명령 앞에 세그먼트 무시 접두사가 없기 때문입니다.
C606011052 mov byte [0x1001],0x52
C606021049 mov byte [0x1002],0x49
C606031046 mov byte [0x1003],0x46
C70604102E00 mov word [0x1004],0x2e
C606051024 mov byte [0x1005],0x24
남은 라인은 메모리에 바이트 단위 가고, 특정 메모리 오프셋에서 바이트 값을 쓰는 그들 모두 덮어 쓰기, 같은 이야기입니다.
다른 라인처럼 유사 타겟 메모리 어드레스
ds:0x1004
을 수행
mov word ptr [msg + 4], '.'
의 미묘한 차이와
하지만, 다른 연산 코드 C7
사용 있도록 저장된 값은 0x002E
('.'
) 동일 imm16
즉 word
값이고 즉 치값은 2 바이트 2E 00
이 필요합니다. 이 주소는 ds:0x1004
바이트의 주소가 2E
이고, ds:0x1005
이 00
인 메모리를 덮어 씁니다.
(내 예제 ds:0x1000
) 주소 msg
의 메모리는 처음에 그래서 경우 :
0x1000: 0A 0D 5A 61 68 69 64 2E 20 24 ; "\n\rZahid. $"
그것은 실행 각 MOV
후이 변경됩니다 :
는
0x1000: 41 0D 5A 61 68 69 64 2E 20 24 ; "A\rZahid. $"
0x1000: 41 52 5A 61 68 69 64 2E 20 24 ; "ARZahid. $"
0x1000: 41 52 49 61 68 69 64 2E 20 24 ; "ARIahid. $"
0x1000: 41 52 49 46 68 69 64 2E 20 24 ; "ARIFhid. $"
0x1000: 41 52 49 46 2E 00 64 2E 20 24 ; "ARIF.\0d. $"
그 단어가 덮어 않았다 2 바이트, 'h'
(점) 및 'i'
(0 포함).
0x1000: 41 52 49 46 2E 24 64 2E 20 24 ; "ARIF.$d. $"
그리고 그 제로 (도스 int 21h
서비스 ah=9
에 대한 문자열 종료) 달러 기호에 한 번 더 덮어 씁니다.
일반적으로 편안한 구문은 문제가되지 않습니다. 사용자가 직접 명령을 작성할 수 없기 때문에 어셈블러는 기존 명령 중 어느 것이 적합한지 추측하고 사용자가 가지고있는 식을 컴파일합니다. mov [address1] and [address2], value
같은 다른 값을 두 개의 다른 메모리 위치에 저장하거나, address
(add [address], 2
은 데이터 크기에 따라 add r/m,imm
variants에서 벗어난 값)으로 메모리 값에 2를 더하는 x86에 대한 지침이 없습니다.
그래서 mov msg+1,...
은 메모리 주소가 msg + 1
일 뿐이며 x86 명령어 세트에는 의미있는 가능성이 없습니다. 그리고 데이터 크기 byte
은 msg:
라벨 뒤에 사용 된 db
지시어에서 공제됩니다. 이것은 MASM과 emu8086 어셈블러의 특수 용도이며, 다른 어셈블러의 대부분은 정의 된 레이블 (기호)을 그 뒤에 사용되는 지시어와 연결하지 않습니다. 즉, "유형 "일반적인 어셈블러의 심볼 그 경우 mov msg+1,'R'
은 구문 오류로 끝날 수 있지만 왼쪽에는 문제가 있기 때문에가 아니라 'R'
값 (얼마나 많은 바이트)이 얼마나 큰지 알 수 없습니다.
내 개인 즐겨 찾기 NASM은 메모리 액세스와 관련하여 대괄호가 필요하므로 NASM에서는 mov [msg+2],...
만 유효합니다 (MASM에서는 "byte ptr"과 같은 크기 한정자를 사용할 수 있지만 "ptr"는 사용할 수 없음) : mov byte [msg+2],...
.하지만 MASM/emu8086에서 사용 된 모든 변형은 동일한 의미의 유효한 구문이며 16b 오프셋으로 메모리 참조를 생성합니다.
어셈블러는 단일 대신에 두 개의 명령어를 생성합니다 (예외적으로 " 명령 "을 참조하십시오. 일부 어셈블러에서는 몇 가지 기본 명령어로 컴파일되지만 x86 어셈블리에서는 일반적이지 않습니다.)
한 번 당신은 대상 CPU 명령어 세트를 알고, 어떤 명령어가 존재하는지, 모호한 구문으로부터 쉽게 추측 할 수 있으며, 어떤 목표 명령어가 생성 될지 알 수 있습니다.
또는 디스어셈블러는 특정 형식의 구문에 대해 단 하나의 구문 만 사용하고 소스 형식의 모호성은 인식하지 않으므로 쉽게 디버거 디스 어셈블리 창을 확인할 수 있습니다.
mov word ptr [msg + 4], '.'
; Confused again as writing on word memory specified by msg+4,
'.' Will it write ascii on the two bytes-> .
그것은 두 바이트에 쓸 것, 즉 MASM에서 WORD PTR
가 지정하는 것입니다. 그러나 그 값은 '.' = 0x2E
입니다. 그러나 0x2E
은 16 비트 값으로도 완벽하게 유효합니다. 즉, 0으로 확장하여 0x002E
으로 간단하게 확장됩니다.이 값은 어셈블러에서이 행에 사용하는 값입니다.
확실하지 않은 경우, 특정 작업을 어셈블하는 방법과 CPU/메모리 상태를 어떻게 처리할지에 대해서는 emu8086 디버거를 사용하십시오. 이 경우에 해치 창에서 msg+x
의 모든 변종이 원래 msg
메모리보다 바이트 단위로 메모리 주소로 컴파일되었음을 알 수 있습니다. 또한 일부 메모리보기 (내가 emu8086 하나 가지고, 그것을 사용하지 마십시오 희망) 주소에서 msg
주소, 당신은 메모리에 쓰기를 볼 수있는 방법을 원래의 값을 변경하고, 그 WORD PTR
어떻게 작동합니다 확실하지 않았다. 디버거를 보는 것은 일반적으로 스택 오버플로에 대한이 긴 대답을 읽는 것보다 훨씬 쉽습니다 ...
PTR의 기능에 대해 : In assembly, what does `PTR` stand for? ... 설명하기가 어렵지만 전체적으로 " BYTE PTR "은 MASM에서 사용하는 용어로, BYTE로 구문 분석하지 않고 BYTE에 PTR을 수행하지만"BYTE PTR "로 구문 분석하고"okay, 그는 바이트 주소 지정 "과 유사합니다. 단일 키워드와 비슷하지만 공간이 있습니다.
무엇을 인쇄 하시겠습니까? 'Arif'와 같은 것을 인쇄해야한다는 코드와 주석을 살펴 보는 것만으로도 분명합니다 (* 이것이 대문자 *라고 기대할지라도). 코드에 'ARIF.'문자가 포함되어 있습니다. –
출력은 '\ n \ rZahid'여야합니다. ARIF.' 정확한 산출물이나 코드를 게시하지 않았습니다. 편집 : 실제로 도스 개행 13,10 바이트 잘못된 순서로, 그래서 '\ r \ n'가 아닌'\ n \ r'을 시작합니다. 당신의 질문은 정확히 무엇입니까? – Ped7g
왜 mov [msg] +2, '나는 생산 오류가 발생하지 않았다. [msg]는 변수의 주소를 반환하고 그 값을 2 씩 증가시키고 어떤 값으로 주소를 초기화하면 실행시 'i'가 나오지 않습니다. –