Intel x86 Assembly Language & Microarchitecture
어셈블러
수색…
Microsoft 어셈블러 - MASM
IBM PC에서 8086/8088이 사용되었고 운영 체제가 Microsoft에서 가장 많이 사용되었다고 가정 할 때 Microsoft의 어셈블러 MASM은 수년 동안 사실상의 표준이었습니다. 인텔의 신택스를 철저히 따랐지만 편리하지만 "느슨한"문법은 (혼자만의 시각으로 볼 때) 혼란과 오류를 일으킨다.
완벽한 예는 다음과 같습니다.
MaxSize EQU 16 ; Define a constant
Symbol DW 0x1234 ; Define a 16-bit WORD called Symbol to hold 0x1234
MOV AX, 10 ; AX now holds 10
MOV BX, MaxSize ; BX now holds 16
MOV CX, Symbol ; ????
마지막 MOV 명령은 Symbol 의 내용 을 CX 에 넣거나 Symbol 의 주소 를 CX 넣습니까? CX 는 0x1234 또는 0x0102 (또는 무엇이든)로 0x0102 나요? CX 는 0x1234 끝납니다. 주소를 원하면 OFFSET 지정자를 사용해야합니다.
MOV AX, [Symbol] ; Contents of Symbol
MOV CX, OFFSET Symbol ; Address of Symbol
인텔 어셈블러
인텔은 8080, 8008 및 4004 프로세서의 파생 제품 인 8086 어셈블리 언어 사양을 작성했습니다. 이와 같이, 그들이 작성한 어셈블러는 정확하게 구문을 따랐습니다. 그러나이 어셈블러는 널리 사용되지 않았습니다.
인텔은 op 코드가 0, 1 또는 2 개의 피연산자를 갖도록 정의했습니다. 두 개의 피연산자 명령어는 그 당시에 다른 어셈블러와 다른 source 순서 인 dest 에 있도록 정의되었습니다. 그러나 일부 명령어는 암시 적 레지스터를 피연산자로 사용했습니다. 인텔은 또한 "접두사"연산 코드 개념을 사용했습니다. 하나의 연산 코드가 다음 명령어에 영향을 미칩니다.
; Zero operand examples
NOP ; No parameters
CBW ; Convert byte in AL into word in AX
MOVSB ; Move byte pointed to by DS:SI to byte pointed to by ES:DI
; SI and DI are incremented or decremented according to D bit
; Prefix examples
REP MOVSB ; Move number of bytes in CX from DS:SI to ES:DI
; SI and DI are incremented or decremented according to D bit
; One operand examples
NOT AX ; Replace AX with its one's complement
MUL CX ; Multiply AX by CX and put 32-bit result in DX:AX
; Two operand examples
MOV AL, [0x1234] ; Copy the contents of memory location DS:0x1234 into AL register
인텔은 다른 어셈블러에서 사용 된 규칙도 위반했습니다. 각 opcode에 대해 서로 다른 니모닉이 발명되었습니다. 이것은 유사한 작업을 위해 미묘하게 또는 뚜렷하게 다른 이름을 필요로했습니다. 예 : "메모리에서로드"에 대한 LDM 과 "로드 즉시"에 대한 LDI . 인텔은 하나의 니모닉 MOV 사용했으며 어셈블러가 문맥에서 사용할 opcode를 찾아 낼 것으로 예상했습니다. 어셈블러가 실제로 프로그래머가 원하는 것을 직관 할 수 없을 때 프로그래머에게 많은 함정과 오류가 발생했습니다 ...
AT & T 어셈블러 - as
8086이 마이크로 소프트와 함께 IBM PC에서 가장 많이 사용되었지만, 다른 컴퓨터와 운영 체제도 많이 사용되었습니다 : 특히 유닉스. 이것은 AT & T의 제품이었으며, 이미 다른 많은 아키텍처에서 유닉스를 운영하고있었습니다. 이러한 아키텍처는보다 일반적인 어셈블리 구문을 사용했습니다. 특히 두 개의 피연산자 명령어로 source , dest 순서로 지정했습니다.
그래서 AT & T 어셈블러 컨벤션이 인텔이 규정 한 컨벤션을 무효로하고, 새로운 범위의 새로운 방언이 x86 계열에 도입되었습니다.
- 레지스터 이름의 접두어는
%:
%al,%bx등 - 즉각적인 가치는
$로 prefied했다 :
$4 - 피연산자가
source,dest순서에 있음 - Opcodes에는 피연산자 크기가 포함됩니다.
movw $4, %ax ; Move word 4 into AX
볼랜드의 Turbo Assembler - TASM
Borland는 "Turbo Pascal"이라고 불리는 파스칼 컴파일러로 시작했습니다. 그 뒤에는 C / C ++, Prolog, Fortran 등 다른 언어 용 컴파일러가 뒤 따랐다. 그들은 또한 "Turbo Assembler"라는 어셈블러를 제작했으며, Microsoft의 명명 규칙에 따라 "TASM"이라고 불렀습니다.
TASM은 지정된 IDEAL 모드에서 소스 코드를보다 엄격하게 해석함으로써 MASM (위 참조)을 사용하여 코드를 작성하는 문제를 해결하려고했습니다. 기본적으로 MASM 모드를 가정 했으므로 MASM 소스를 직접 어셈블 할 수있었습니다. 그러나 Borland는 MASM의보다 "기발한"고유 모드와 버그에 부합해야한다는 것을 알았으므로 QUIRKS 모드를 추가했습니다.
TASM은 MASM보다 훨씬 저렴했기 때문에 사용자 기반이 컸지 만 선전 된 장점에도 불구하고 IDEAL 모드를 사용하는 사람은 많지 않았습니다.
GNU 어셈블러 - 가스
GNU 프로젝트가 x86 계열을위한 어셈블러를 필요로 할 때 그들은 Intel / Microsoft 버전이 아닌 Unix와 관련된 AT & T 버전 (및 구문)을 사용했습니다.
Netwide 어셈블러 - NASM
NASM은 x86 아키텍처에서 가장 많이 이식 된 어셈블러입니다. x86 기반의 거의 모든 운영 체제에서 사용할 수 있으며 (MacOS에도 포함되어 있음) 다른 플랫폼에서 크로스 플랫폼 어셈블러로 사용할 수 있습니다.
이 어셈블러는 Intel 구문을 사용하지만 자체 "매크로"언어에 집중하기 때문에 다른 구문과 다릅니다. 프로그래머가 간단한 정의를 사용하여 더 복잡한 표현식을 작성하여 새로운 "명령어"를 만들 수 있습니다.
불행히도이 강력한 기능은 비용이 들게됩니다. 데이터 유형이 일반화 된 명령어의 방식에 포함되므로 데이터 유형 지정이 강제되지 않습니다.
response: db 'Y' ; Character that user typed
cmp response, 'N' ; *** Error! Unknown size!
cmp byte response, 'N' ; That's better!
cmp response, ax ; No error!
그러나 NASM은 다른 사람들이 부족한 특징 인 스코프 된 심볼 이름을 도입했습니다. 다른 어셈블러에서 심볼을 정의하면 나머지 코드에서 해당 이름을 사용할 수 있습니다.하지만이 이름은 전역 이름 공간을 심볼로 "오염"시키는 "해당 이름을 사용합니다".
예를 들어 (NASM 구문 사용) :
STRUC Point
X resw 1
Y resw 1
ENDSTRUC
이 정의 후에, X와 Y는 영원히 정의됩니다. X 와 Y 라는 이름을 "사용하지 않으려면"더 명확한 이름을 사용해야했습니다.
STRUC Point
Pt_X resw 1
Pt_Y resw 1
ENDSTRUC
그러나 NASM은 대안을 제시합니다. "지역 변수"개념을 활용하여 향후 참조 할 때 포함 구조를 지정해야하는 구조 필드를 정의 할 수 있습니다.
STRUC Point
.X resw 1
.Y resw 1
ENDSTRUC
Cursor ISTRUC Point
ENDISTRUC
mov ax,[Cursor+Point.X]
mov dx,[Cursor+Point.Y]
불행히도, NASM은 타입을 추적하지 않기 때문에 더 자연스러운 구문을 사용할 수 없습니다 :
mov ax,[Cursor.X]
mov dx,[Cursor.Y]
또 다른 어셈블러 - YASM
YASM 은 NASM을 완전히 다시 작성했지만 Intel 및 AT & T 구문과 호환됩니다.