대부분의 어셈블러는 source file을 두 번 읽는다.
printf
는 symbol인건 알겠는데 코드만으로는 뭔지 알 수가 없다. 라이브러리에 정의되어있기 때문임. 어셈블리 파일에 definition이 존재하지 않아서 resolve할 수 없고 value를 생성해낼 수 없음. 하지만 linking의 과정을 수행하면 그 때에 linker를 통해 printf
를 resolve할 수 있음.몇 개의 symbol은 known value를 가지고 있지 않을 수 있다.
그 symbol들은 unresolved이며 linker가 그 값들을 fix한다.
:
로 끝난다.;
로 끝난다..
으로 시작한다.label:
instruction[;]
.directive[;]
macro_invocation[;]
// single-line comment
@ single-line commnet in AArch32 state only
/* multi-line
comment */
expression은 instruction operand나 directive argument로 사용될 수 있다.
expression은 operator로 결합된 한 개 혹은 그 이상의 constant나 symbol reference로 이루어져 있다.
assembler가 모든 expression을 evaluate한다. expression의 value를 calculate한다는 의미이다. 어셈블러가 compile time에 value를 계산한다. CPU가 runtime에 하는 것이 아니라.. 미리 계산한다는 의미.
symbol은 반드시 같은 assembly language source file에 정의되거나 expression에 reference될 필요는 없다.
period symbol .
은 output file의 current location을 reference할 수 있는 special symbol이다.
section의 type을 specify함.
.section name
.text
: text section.data
: data section.rodata
: read only data section.bss
현재 section에 one or more bytes를 할당해서 string literal로 memory content를 initialize함.
.ascii "string"
: 공간을 allocate해서 string
을 넣지만 string
뒤에 null byte를 넣지 않는다. C 랑 combine해서 쓰는 경우 이건 쓰면 안된다. null character가 없기 때문에 문자열이 끝나지 않기 때문이다..asciz "string"
, .string "string"
: string
을 넣고 그 뒤에 null byte를 append한다.current section에 memory를 allocate하고 그 memory의 initial content를 정의한다.
given value로 space를 채운다.
.byte expr[, expr]...
: multiple expression이 가능하고 byte를 할당해 expression의 결과로 space를 채운다..hword expr[, expr]...
.word expr[, expr]...
.quad expr[, expr]...
.octa expr[, expr]...
// 1 byte에 42를 넣음
.byte 42
// 1 word(4 byte)에 15532를 넣음
.word 15532
// 1 word에 extern_symbol의 address를 넣음
.word extern_symbol
// 2 byte에 end와 start의 distance를 계산해서 넣음
// end의 address에서 start의 address를 뺐으므로 distance가 됨
.hword end - start
// 4 byte에 extern_symbol이 current location에서 얼마나 떨어져 있는지 distance를 넣음
.word extern_symbol - .
alignment directive는 file의 current location을 specified boundary로 aligh해준다.
.balign num_bytes[, fill_value]
: balign
의 b
는 byte이다..p2align exponent[, fill_value]
: p2align
의 p2
는 power 2이다..align exponent[, fill_value]
num_bytes
: 이 parameter은 align되어야 하는 number of bytes를 나타낸다. 이 number은 반드시 2의 지수여야 한다.
exponent
: 이 parameter은 alignment boundary를 exponent로 나타낸다. 이 alignment boundary는 2^(exponent)
이다.
fill_value
: 삽입된 padding bytes를 채울 값. 이 값은 optional이다.
.p2align 2
value:
.word 42 // 2^2 = 4 byte boundary로 align됨.
.p2align 4 // function의 entry point가 16-bytes boundary로 align되는 것을 보장함. to better utilize cache
.type func1, "function"
func1:
//code
.space count[, value]
: count
는 item의 개수이고 value
는 item의 initial value이다. .space
는 value
값을 가지고 있는 count
만큼의 bytes를 할당한다..fill count[, size[, value]]
: size
는 item의 initial size이다. .fill
은 size
만큼의 length에 value
값을 가진 count
만큼의 공간을 만든다..macro macro_name [, parameter_name]
// ..
[.exitm]
.endm
macro_name
: macro의 name이다.
parameter_name
: macro의 모든 parameter가 나열된다. macro 내부에서 이 parameter를 사용하기 위해서는 prefix \
를 써야 한다.
.macro
는 macro_name
의 새로운 macro를 정의한다. macro가 한 번 정의되고 나면 instruction mnemonic처럼 instantiate될 수 있다.
macro_name argument[, argument] ...
.macro pascal_string, str //one parameter를 가진 macro
.byte 2f - 1f //label 사이의 distance를 구함. f는 forward를 의미함. symbol의 location이 있을 텐데 그 symbol의 forward position을 의미함.
1:
.ascii "\str" //space를 allocate해서 string을 넣었지만 terminator가 없음.
2:
.endm
.org
는 location counter를 current section에서 new-location으로 증가시킨다.
location counter은 forward로만 움직이고 backward로는 움직이지 않는다.
.org new_location[, fill_value]
new_location
: mendatory parameter임. current section의 location을 evaluate하기 위한 expression이다.fill_value
: optional 1 byte이고 default value는 0이다. .macro exc_tab_entry, num //vector table을 initialize하기 위한 macro
1:
mov x0, #\num
b unhandled_exception
.org 1b + 0x80 //labal 1의 backward position에서 128 bytes로 counter를 next entry의 beginning으로 옮길 수 있다.
.endm
.if[modifier] expression
//...
[.elseif expression
//...]
[.else
//...]
.endif
모든 directive는 assembler로 evaluate된다!
어셈블러가 calculate하는거라 런타임에서는 directive를 볼 수 없음.
.if expr
: expr
이 non zero일때 following code를 assemble함..ifne expr
: expr
이 non zero일때 following code를 assemble함..ifeq expr
: expr
이 zero일때 following code를 assemble함.한 개 혹은 그 이상의ELF
binding을 modify한다.
.global symbol[, symbol]
: link된 모든 object file에게 visible하다. 한 object file의 definition이 다른 object file에서 reference될 수 있다. strong binding..local symbol[, symbol]
: define되거나 reference된 object file 밖에서는 이 symbol들이 보이지 않는다. 그래서 여러 object file이 서로의 간섭 없이 같은 symbol 이름을 사용할 수 있다..weak symbol[, symbol]
: 이 symbol들은 global symbol들과 비슷하지만 차이점이 있다.symbol binding directive는 assembly의 어느 지점에서나 나올 수 있다. symbol의 어떤 reference나 definition의 앞이나 뒤에 나올 수 있다.
만약 symbol의 binding이 specify되지 않았다면 default는 다음과 같다
.weak debug_trace
bl debug_trace
위의 예제에서 debug_trace
는 global visibility를 가진 weak binding이다. 다른 어셈블리 파일에 debug_trace
가 있고 그 파일에 debug_trace
이 global definition으로 되어있다면 얘는 그 global definition을 가리키게 되지만 그것이 없다면 다른 global definition들이 얘를 가리키게 됨.
.arm
: 어셈블러가 이후의 instruction을 A32
instruction으로 해석한다..thumb
: 어셈블러가 이후의 instruction을 UAL
syntax를 사용하는 T32
instruction으로 해석한다..thumb_func
: 이후 나오는 symbol이 Thumb encoded function의 이름임을 나타낸다..syntax [unified | divided]
: 이 directive는 instruction set syntax를 설정한다.UAL
(unified assembly language) syntax를 enable한다. Thumb2
instruction을 위해 필요하다.