2016-12-13 6 views
2

어셈블리 언어를 사용하고 있지 않습니다. 나는 최근에 비참한 무언가에 들어갔다.

head.h을

#define _Length_ 0x0A 

main.S

movw $_LENGTH_, %ax 
movw _LENGTH_, %ax 

이제 두 MOV 문의 차이점은 무엇입니까

다음과 같이 나는 샘플 어셈블리 프로그램을 만들어? 도끼의 가치는 무엇입니까?

우분투 및 GAS 어셈블러 (AT & T 구문)를 사용하고 있습니다. 사전에

감사

+0

movw $ _ LENGTH _, % ax는 0x0a의 즉치 값을 ax로 이동시키는 반면 movw _ LENGTH_, % ax는 메모리의 0x0a 위치에서 % ax로 16 비트 단어를 이동하려고 시도합니다. – rcgldr

답변

5

$ 및 & T 구문이 간단 (인간을 위해 반드시 어셈블러 용) 구문 분석 할 수 AT에서 % 장식.


나는 당신이 실제로 #define _LENGTH_ 0x0A 대신 #define _Length_ 0x0A을 쓴 척하는거야.

그렇지 않은 경우 _LENGTH_은 어셈블러에서 외부 심볼로 처리되며 _Length_은 아무데도 대체되지 않는 정의 된 매크로이므로 어셈블러는 존재하지 않습니다. C 프리 프로세서는 항상 즉시 일정 의미 단지

$


C.

처럼, 어셈블러는 완전히 별개입니다. 따라서 movw $0x0A, %ax은 0xA를 AX에 넣습니다.

피연산자로 $이없는 숫자 또는 기호는 항상 메모리 피연산자를 의미합니다. movw 0x0A, %ax은 주소 [ds:0xA]에서 AX 로의로드입니다 (실효 주소는 NASM 표기법을 사용). 이것은 거의 당신이 원하는 것이 아닙니다.


movw $undefined_symbol, %ax 조립합니다 (.o의 재배치 정보를 볼 objdump -drwC 사용),하지만 링크시 실패합니다.

+0

ljmp $ 0, _LENGTH_는 어떻게됩니까? 이 성명서는 무엇을 할 것입니까? 감사. –

+0

@PantherCoder : 분명히'ljmp'는'far jmp'의 가스 니모닉입니다. 즉각적인 세그먼트가 있지만 메모리 간접 오프셋이있는 [JMP 인코딩 없음] (http://www.felixcloutier.com/x86/JMP.html)이므로 어셈블 할 수 없습니다. 'ljmp $ 0, $ 0xa'는 (32 비트 모드에서만, 64 비트 모드에서는 ljmp를 지원하지 않습니다.) 어셈블됩니다. 그러나'gcc -c -m32','ljmp $ 0, 0xa' :'gcc -m32'는'Error : 'ljmp'에 대한 피연산자 타입 불일치를 말합니다. 또한,'ljmp $ 0, $ some_symbol'은 잘 어셈블되며, 당신이 점프하고있는 코드 세그먼트가 현재베이스와 동일한베이스를 가지고 있다면 실제로 작동 할 것입니다. –