>> | Аноним Пятница 26 Дек 2014 20:32:04 Пт 26 Дек 2014 20:32
No.
1144386
[Мод] меня прислал пинки, не знаю зачем.
массив - это адрес в памяти. просто адрес. когда мы делаем
char x[] = "xyz"; а потом обращаемся к x[2] мы знаем _адрес_, с которого начинается x, прибавляем к нему 2 и получаем результат.
указатель - это переменная, в которой лежит адрес. к её значению можно прибавить два и достать что-то по новому адресу, поэтому работает такое:
char* y = &x; z = y[2];
теперь профы: сорц:
rakul@lucky-star /tmp $ cat test.c
char array[10] = "abcd";
char* ptr = "abcd";
int main()
{
char a = array[2];
char b = ptr[2];
return 0;
}
асм:
rakul@lucky-star /tmp $ gcc -S -o test.asm test.c
rakul@lucky-star /tmp $
rakul@lucky-star /tmp $
rakul@lucky-star /tmp $ cat test.asm
.file "test.c"
.globl array
.data
.type array, @object
.size array, 10
array:
.string "abcd"
.zero 5
.globl ptr
.section .rodata
.LC0:
.string "abcd"
.data
.align 8
.type ptr, @object
.size ptr, 8
ptr:
.quad .LC0
.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
movzbl array+2(%rip), %eax
movb %al, -2(%rbp)
movq ptr(%rip), %rax
movzbl 2(%rax), %eax
movb %al, -1(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Gentoo 4.9.1 p1.0, pie-0.6.0) 4.9.1"
.section .note.GNU-stack,"",@progbits
во -певых обратите внимание на то, что для массивы мы имеем просто объявление: array: .string "abcd" .zero 5 .globl ptr .section .rodata а для указателя уже: .LC0: .string "abcd" .data .align 8 .type ptr, @object .size ptr, 8 ptr: .quad .LC0 .text .globl main .type main, @function
а во вторых вот тут собственно доступ:
к массиву: movzbl array+2(%rip), %eax movb %al, -2(%rbp) movq ptr(%rip), %rax к указателю: movzbl 2(%rax), %eax movb %al, -1(%rbp) movl $0, %eax
для массива мы просто берём array+2. потому что array это ИЗНАЧАЛЬНО просто адрес. а для указателя мы берёт значение переменной (указателя) из регистра (вот тут): movzbl 2(%rax), %eax чтобы вытащить адрес из него.
всем спасибо.
зы. я тред не читал, кто прав, кто виноват мне всё равно.
|