AT_T어셈블리어실습

Download Report

Transcript AT_T어셈블리어실습

AT&T 어셈블리어 II
2008. 06. 08. 한승후
목차
심볼
 화이트 공백문자
 전처리
 라벨, 상수, 예약어, 식별자, 디렉티브,
명령어
 섹션과 재배치
 Intel과 AT&T 문법 비교
 Hello, world!

심볼
심볼은 한글자 이상으로 대소문자와 십진수,
'_.$'로 조합되는 것이다.
 심볼은 10진수로 시작하지 않는다. 심볼을
만들어 내는 방법은 많으며 길이의 제한도
없다.
 점 심볼


'.'은 as가 어셈블하고 있는 현재의 주소를
참조한다. 그래서, 표현식 'melvin: .long .'은
melvin을 그것 자신의 주소를 포함하도록 한다.
화이트 공백문자
화이트 공백문자(whitespace)는 하나이상의
빈칸이거나 탭 등이 될 수 있다. 화이트
문자는 심볼들을 분리하는 데 사용되며
사람들이 프로그램을 쉽게 읽을 수 있도록
만든다. 문자 상수가 아니라면, 어떠한
화이트문자도 하나의 공백문자로 취급된다.
 instruction operand_1, operand_2, ...

전처리
여분의 공백(whitespace)들을 적절히
조절하고 제거한다. 한 라인상에서 키워드
앞에 하나의 공백(space)이나 탭을 남긴다.
 모든 주석을 제거하고, 그것을 하나의
공백문자로 치환하거나 새로운 라인의
적당한 번호로 치환한다.
 문자 상수값을 적당한 숫자 값으로
변환한다. 공백문자들과, 주석, 문자
상수들의 지나친 사용은 전치리 되지 않은
입력 파일의 일부로서 사용될 수 없다.

라벨
라벨은 바로 뒤에 콜론(':')이 따라오는
하나의 심볼이다. 화이트 문자는 라벨의
앞이나 콜론의 뒤에 오는 것이 허용된다.
 하지만 라벨의 심볼과 콜론 사이에는 화이트
공백문자가 올 수 없다.

label: .directive followed by something
 another_label: # This is an empty statement.

상수
하나의 상수는 하나의 숫자
 예를 들면,

# All the same value
.byte 74, 0112, 092, 0x4A, 0X4a, 'J, '\J
 .ascii "Ring the bell\7"
 # A bignum
.octa 0x123456789abcdef0123456789ABCDEF0
 .float 0f-314159265358979323846264338227\
 #pi, a flonum
95028841971.693993751E-40

예약어
인텔 프로세서에 의해 실행되는 mov, add,
mul과 같은 명령어 니모닉
 as에게 어떻게 프로그램을 어셈블해야
하는지 알려 주는 디렉티브들
 .byte 혹은 .word 같이 변수나 피연산자의
크기나 사용처를 알려 주는 속성들
 수식에 사용되는 연산자들(+,-,*,/)

식별자(label)
프로그래머가 선택한 이름이다. 변수나
상수, 프로시저 혹은 코드 레이블 등에
사용된다.
 식별자는 어셈블리의 예약어와 같을 수
없다.

디렉티브(directive)
프로그램의 소스 코드를 어셈블할 때
어셈블러가 인식하고 활용하는 명령어이다.
 논리 세그먼트를 정의, 메모리 모델을 선택,
변수를 정의, 프로시저를 만들 때 사용
 .data, .text, .code 등

명령어(instruction)


프로그램이 메모리에 탑재되어 실행될 때 프로세서에
의하여 실행되는 문장
명령어는 기본적으로 4개의 부분으로 구성된다.
1. 레이블(선택사항) - 명령어 혹은 데이터의 위치를 표시하는 하나의
식별자이다. 소스 프로그램을 스캔할 때 어셈블러는 각 프로그램
문장에 숫자 주소를 할당한다.

코드 레이블 : 프로그램의 코드 영역(명령어가 있는 영역)에서
레이블은 콜론(;)으로 끝난다. 일한 문에서 레이블은 점프나 루프
명령어에 사용된다.


target: move ax, bx
데이터 레이블 : 만약 레이블이 프로그램의 데이터 영역(변수가 정의된
영역)에서 사용될 경우 콜론으로 끝날 수 없다.

first BYTE 1
2. 명 령 니모닉(필수) - 명령어에 의하여 수행되는 동작을 식별하기
위한 짧은 단어이다. mov, add, sub, mul, jmp, call 등과 같은 이름을
갖는지를 설명한다.
3. 피연산자들(보통 필수)
4. 주석(선택사항)
섹션과 재배치






섹션은 빈틈이 없는 어드레스들의 범위이다.
섹션 안에 있는 모든 데이터들은 같은 어떤 특별한 목적으로 취급된다.
링커 ld는 많은 목적 파일 (프로그램의 일부분인)을 읽어들여서
그것들을 결합하여 실행가능한 프로그램 형식을 구성한다. as가 목적
파일을 만들어낼 때 그 부분적인 프로그램은 어드레스 0에서 시작하는
것으로 가정된다. ld 는 마지막 어드레스를 그 부분적인 프로그램으로
할당하는 데, 그래서 다른 부분적인 프로그램들이 겹쳐지지 않는다.
이것은 실지로 하나의 간략화이다.
ld 는 프로그램의 블록 바이트를 이들의 실행시간 주소로 옮긴다.
이러한 블록들은 이들의 실행시간 주소로 바뀐다. 이들 블록들의
길이는 변하지 않는다. 이러한 블록을 섹션(section)이라고 부른다.
실행시 주소를 섹션에 할당하는 것을 "재배치(relocation)"라 부른다.
'relocation'은 목적 파일의 주소의 기록을 조절하는 테스크를 포함
하는데, 그래서 그들은 고유의 실행 시간 주소로 참조된다.
.text, .code, .data, .bss 등
Intel/AT&T 문법 비교 - 1
immediate value, $
 AT&T에서 즉시적인 피연산자 앞에는 '$'이
붙는다. 인텔에서의 즉시적인 피연산자에는
제한이 없다

Intel: 'push 4‘
 AT&T: 'pushl $4'

Intel/AT&T 문법 비교 - 2
register naming, %
 AT&T 레지스터 피연산자 앞에는 '%'이
붙는다; 인텔 레지스터 피연산자에는 제한이
없다.

Intel/AT&T 문법 비교 - 3
source/dest ordering
 AT&T 와 인텔 문법은 source피연산자와
dest피연산자의 순서가 서로 뒤 바뀌어져
있다.

Intel: 'add eax, 4‘
 AT&T: 'addl $4, %eax‘


이전의 유닉스 어셈블러들과의 호환성을
위해 이런 방식을 택함
Intel/AT&T 문법 비교 - 4


operator size specification
AT&T 문법에서 메모리 피연산자의 크기는 작동자
이름의 마지막 글자로 검사된다. 작동자에는 'b',
'w', 'l'의 접미사가 붙는다. 이것은 각각 byte (8bit), 워드(16-bit), long (32-bit)메모리 참조를
의미한다. 인텔 문법에서는 이러한 것들을 메모리
피연산자 앞에 'byte ptr', 'word ptr' 과 같은
접두사를 붙임으로써 (작동자(opcode)에 붙는
것이 아닌) 해결한다. 그래서


Intel: 'mov al, byte ptr FOO‘
AT&T'movb FOO, %al'
Intel/AT&T 문법 비교 - 5


메모리를 간접적으로 참조하는 형식
Intel


AT&T


SECTION:[BASE + INDEX*SCALE + DISP]
SECTION:DISP(BASE, INDEX, SCALE)
예제




Intel:
AT&T:
Intel:
AT&T:
[ebp - 4]
-4(%ebp)
[foo + eax*4]
foo(,%eax,4),
Intel/AT&T 문법 비교 - 6

far jump와 call
AT&T: lcall/ljmp $SECTION, $OFFSET
 Intel: call/jmp far SECTION:OFFSET


far return 명령
Intel: ret far STACK-ADJUST
 AT&T: lret $STACK-ADJUST‘

Intel/AT&T 문법 비교 - 7

AT&T 어셈블러는 다중 섹션 프로그램을
위한 지원을 하지 않는다. 유닉스 스타일의
시스템들은 모든 프로그램들이 싱글
섹션이라고 생각한다.
Hello, world!
;Intel, nasm
section .text
global _start
_start:
;write our string to stdout
mov
edx,len
mov
ecx,msg
mov
mov
int
;and exit
mov
mov
int
ebx,1
eax,4
0x80
ebx,0
eax,1
0x80
section .data
msg
db
"Hello, world!",0xa
len
equ
$ - msg
#AT&T, as
.text
.global _start
_start:
# write our string to stdout
movl $len,%edx # third argument: message length
movl $msg,%ecx # second argument: pointer to
# message to write
movl $1,%ebx
# first argument: file handle (stdout)
movl $4,%eax
# system call number (sys_write)
int
$0x80
# call kernel
# and exit
movl $0,%ebx
# first argument: exit code
movl $1,%eax
# system call number (sys_exit)
int
$0x80
# call kernel
.data
# section declaration
msg:
.ascii "Hello, world!\n" # our dear string
len = . - msg
# length of our dear string
Q&A