다음은 간단하게 배열과 포인터를 각각 사용하는 c 코드와 그로부터 만들어진 어셈블리 코드이다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
char a[] = "abc"; | |
int main(void) | |
{ | |
printf("%p\n", a); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "arr.c" | |
.globl a | |
.data | |
.type a, @object | |
.size a, 4 | |
a: | |
.string "abc" | |
.section .rodata | |
.LC0: | |
.string "%p\n" | |
.text | |
.globl main | |
.type main, @function | |
main: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register 6 | |
movl $a, %esi | |
movl $.LC0, %edi | |
movl $0, %eax | |
call printf | |
movl $0, %eax | |
popq %rbp | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size main, .-main | |
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3" | |
.section .note.GNU-stack,"",@progbits |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
char *a = "abc"; | |
int main(void) | |
{ | |
printf("%p\n", a); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "ptr.c" | |
.globl a | |
.section .rodata | |
.LC0: | |
.string "abc" | |
.data | |
.align 8 | |
.type a, @object | |
.size a, 8 | |
a: | |
.quad .LC0 | |
.section .rodata | |
.LC1: | |
.string "%p\n" | |
.text | |
.globl main | |
.type main, @function | |
main: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register 6 | |
movq a(%rip), %rax | |
movq %rax, %rsi | |
movl $.LC1, %edi | |
movl $0, %eax | |
call printf | |
movl $0, %eax | |
popq %rbp | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size main, .-main | |
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3" | |
.section .note.GNU-stack,"",@progbits |
arr.s의 6, 7라인. 그리고 22라인을 보자.
어레이의 경우는 리터럴의 시작주소가 곧 자신의 위치이다.
따라서 접근을 할 때, $a와 같이 해당 심볼의 위치를 바로 가져온다.
ptr.s에서는 4,5,10,11라인. 그리고 26라인을 보자.
반면, 포인터는 리터럴의 시작주소를 값으로 가진다.
따라서 접근 시, a(%rip)와 같이, rip relative 방식으로 해당 변수의 '값'을 가져온다.