Skip to content

Latest commit

 

History

History
executable file
·
150 lines (128 loc) · 6.29 KB

string-array-dan-pointer.md

File metadata and controls

executable file
·
150 lines (128 loc) · 6.29 KB

String, Array dan Pointer

Array

Dalam pemrograman array merupakan variable yang dapat memiliki banyak nilai dengan tipe data yang sama. Contohnya seperti kode C dibawah ini.

#include <stdio.h>

int main(void)
{
    int arr[] = {10, 20, 30, 40};
    return 0;
}

Kita coba lihat assemblynya

$ gcc -o array array.c
$ gdb -batch -ex 'file array' -ex 'disas main'
Dump of assembler code for function main:
   0x0000000000400497 <+0>:     push   rbp
   0x0000000000400498 <+1>:     mov    rbp,rsp
   0x000000000040049b <+4>:     mov    DWORD PTR [rbp-0x10],0xa
   0x00000000004004a2 <+11>:    mov    DWORD PTR [rbp-0xc],0x14
   0x00000000004004a9 <+18>:    mov    DWORD PTR [rbp-0x8],0x1e
   0x00000000004004b0 <+25>:    mov    DWORD PTR [rbp-0x4],0x28
   0x00000000004004b7 <+32>:    mov    eax,0x0
   0x00000000004004bc <+37>:    pop    rbp
   0x00000000004004bd <+38>:    ret    
End of assembler dump.

Jika kita lihat assemblynya, program seperti memiliki 4 variable yang berlokasi rbp-0x10, rbp-0xc, rbp-0x8, rbp-0x4 yang sebenarnya itu adalah 1 variable bertipe array yang mempunyai 4 elemen.

Contoh dibawah ini adalah kode C untuk mengakses elemen pada array.

#include <stdio.h>

int main(void)
{
    int arr[] = {10, 20, 30, 40};
    int y = arr[2];
    return 0;
}

Kode assemblya akan seperti ini.

$ gcc -o array array.c
$ gdb -batch -ex 'file array' -ex 'disas main'
Dump of assembler code for function main:
   0x0000000000400497 <+0>:     push   rbp
   0x0000000000400498 <+1>:     mov    rbp,rsp
   0x000000000040049b <+4>:     mov    DWORD PTR [rbp-0x20],0xa
   0x00000000004004a2 <+11>:    mov    DWORD PTR [rbp-0x1c],0x14
   0x00000000004004a9 <+18>:    mov    DWORD PTR [rbp-0x18],0x1e
   0x00000000004004b0 <+25>:    mov    DWORD PTR [rbp-0x14],0x28
   0x00000000004004b7 <+32>:    mov    eax,DWORD PTR [rbp-0x18]
   0x00000000004004ba <+35>:    mov    DWORD PTR [rbp-0x4],eax
   0x00000000004004bd <+38>:    mov    eax,0x0
   0x00000000004004c2 <+43>:    pop    rbp
   0x00000000004004c3 <+44>:    ret    
End of assembler dump.

Kita lihat diatas, variable arr pada elemen kedua akan diisi dengan nilai 30, variable arr elemen kedua memiliki lokasi memory di [rbp-0x18]. Pada main+32 variable arr pada elemen kedua akan disimpan di eax, dan nilai eax akan disimpan di [rbp-0x4], [rbp-0x4] merupakan lokasi variable y.

Sekarang kita membuat contoh lain. Contoh dibawah ini merupakan contoh pengaksesan seluruh elemen array dengan perulangan for. Kodenya seperti ini.

#include <stdio.h>

int main(void)
{
    int arr[] = {10, 20, 30, 40};
    int i;
    for(i = 0; i < 4; i++)
    {
        printf("%d\n", arr[i]);
    }
    return 0;
}
$ gcc -o array array.c
$ gdb -batch -ex 'file array' -ex 'disas main'
Dump of assembler code for function main:
   0x00000000004004e7 <+0>:     push   rbp
   0x00000000004004e8 <+1>:     mov    rbp,rsp
   0x00000000004004eb <+4>:     sub    rsp,0x20
   0x00000000004004ef <+8>:     mov    DWORD PTR [rbp-0x20],0xa
   0x00000000004004f6 <+15>:    mov    DWORD PTR [rbp-0x1c],0x14
   0x00000000004004fd <+22>:    mov    DWORD PTR [rbp-0x18],0x1e
   0x0000000000400504 <+29>:    mov    DWORD PTR [rbp-0x14],0x28
   0x000000000040050b <+36>:    mov    DWORD PTR [rbp-0x4],0x0
   0x0000000000400512 <+43>:    jmp    0x400534 <main+77>
   0x0000000000400514 <+45>:    mov    eax,DWORD PTR [rbp-0x4]
   0x0000000000400517 <+48>:    cdqe
   0x0000000000400519 <+50>:    mov    eax,DWORD PTR [rbp+rax*4-0x20]
   0x000000000040051d <+54>:    mov    esi,eax
   0x000000000040051f <+56>:    lea    rdi,[rip+0xae]        # 0x4005d4
   0x0000000000400526 <+63>:    mov    eax,0x0
   0x000000000040052b <+68>:    call   0x4003f0 <printf@plt>
   0x0000000000400530 <+73>:    add    DWORD PTR [rbp-0x4],0x1
   0x0000000000400534 <+77>:    cmp    DWORD PTR [rbp-0x4],0x3
   0x0000000000400538 <+81>:    jle    0x400514 <main+45>
   0x000000000040053a <+83>:    mov    eax,0x0
   0x000000000040053f <+88>:    leave
   0x0000000000400540 <+89>:    ret
End of assembler dump.

Kode assembly yang dihasilkan cukup panjang, tapi saya akan membahasnya satu-satu. Pertama, pada main+8 sampai main+29 itu adalah bagian dimana variable array arr diinisialisasi. Pada main+36 variable i diinisialisai dengan 0. Pada main+43 sampai main+81 itu merupakan bagian kode pada blok for.

Kita langsung fokus pada inti kode yang berada didalam for, kode yang for berada pada main+45 sampai main+68. Variable counter yakni variable i berlokasi pada [rbp-0x4]. Pada main+45 variable i disimpan di register eax, setelah itu ada instruksi cdqe, instruksi cdqe akan mengkonversi nilai dword pada eax menjadi qword.

Pada main+50 terdapat instruksi mov eax,DWORD PTR [rbp+rax*4-0x20], instruksi ini akan mengakses elemen ke i pada variable arr. Angka -0x20 digunakan untuk menunjuk ke variable array, karena variable i berlokasi di rbp-0x20. Sementara rax*4 akan menghasilkan offset untuk menunjuk ke elemen pada variable array. Jika kita lihat di instruksi sebelumnya, register rax telah diisi oleh variable i. Jadi nilai i*4 digunakan untuk menunjuk nilai elemen ke i pada array. Sementara, angka 4 merupakan besar dari tipe data integer, karena tipe integer mempunyai besar 4 byte.

Pointer

Pointer merupakan variable yang menyimpan alamat memory untuk variable lain, seperti contoh kode C dibawah ini.

#include <stdio.h>

int main(void)
{
    int a = 10;
    int *p = &a;
}

Sekarang kita compile dan lihat hasil assemblynya.

$ gcc -o pointer pointer.c
$ gdb -batch -ex 'file pointer' -ex 'disas main'
Dump of assembler code for function main:
   0x0000000000400497 <+0>:     push   rbp
   0x0000000000400498 <+1>:     mov    rbp,rsp
   0x000000000040049b <+4>:     mov    DWORD PTR [rbp-0xc],0xa
   0x00000000004004a2 <+11>:    lea    rax,[rbp-0xc]
   0x00000000004004a6 <+15>:    mov    QWORD PTR [rbp-0x8],rax
   0x00000000004004aa <+19>:    mov    eax,0x0
   0x00000000004004af <+24>:    pop    rbp
   0x00000000004004b0 <+25>:    ret    
End of assembler dump.

Variable a berlokasi di rbp-0xc. Pada main+11 terdapat instruksi lea yang akan menghasilkan alamat memory untuk variable i. hasil dari instruksi lea akan disimpan di register rax dan rax yang telah berisi alamat memory akan disimpan di rbp-0x8. rbp-0x8 merupakan lokasi memory untuk variable pointer p.