Мне сказали c-часто-задаваемые-вопросы, что компилятор делает разные вещи для контакта со [мной] в то время как массива или указателя. Вот пример от c-часто-задаваемых-вопросов:
char a[] = "hello"; char *p = "world";
Учитывая объявления выше, когда компилятор видит выражение a [3], он испускает код, чтобы запуститься в местоположении, переместить три прошлое это и выбрать символ там. То, когда это видит выражение p [3], это испускает код, чтобы запуститься в местоположении ''p'', выбрать значение указателя там, добавить три к указателю и наконец выбрать символ, указало.
Но мне сказали, что при контакте со [мной], компилятор имеет тенденцию преобразовывать (который является массивом) к указателю на массив. Таким образом, я хочу видеть ассемблерные коды для обнаружения, который является правильным.
Править:
Вот источник этого оператора. c-часто-задаваемые-вопросы И примечание это предложение:
выражение формы [я] заставляет массив затухать в указатель, после правила выше, и затем преобразовываться в нижний индекс, как была бы переменная указателя в выражении p [я] (хотя возможные доступы памяти будут отличаться,"
Я довольно смущен этого: так как затух к указателю, тогда почему он имеет в виду о "доступах памяти, будет отличаться?"
Вот мой код:
// array.cpp
#include
using namespace std;
int main()
{
char a[6] = "hello";
char *p = "world";
printf("%c\n", a[3]);
printf("%c\n", p[3]);
}
И вот часть ассемблерного кода, я получил использование g ++-S array.cpp
.file "array.cpp"
.section .rodata
.LC0:
.string "world"
.LC1:
.string "%c\n"
.text
.globl main
.type main, @function
main:
.LFB2:
leal 4(%esp), %ecx
.LCFI0:
andl $-16, %esp
pushl -4(%ecx)
.LCFI1:
pushl %ebp
.LCFI2:
movl %esp, %ebp
.LCFI3:
pushl %ecx
.LCFI4:
subl $36, %esp
.LCFI5:
movl $1819043176, -14(%ebp)
movw $111, -10(%ebp)
movl $.LC0, -8(%ebp)
movzbl -11(%ebp), %eax
movsbl %al,%eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
movl -8(%ebp), %eax
addl $3, %eax
movzbl (%eax), %eax
movsbl %al,%eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
movl $0, %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
Я не могу выяснить механизм [3] и p[3] от кодов выше. Такой как:
И, отметьте эти 3 строки кодов:
movl 1 819 043 176$,-14 (%ebp)
movw 111$,-10 (%ebp)
$ movl.LC0,-8 (%ebp)
Последний использует "movl", но почему он не перезаписывал содержание-10 (%ebp)? (Я знаю anser теперь:), адрес является возрастающим, и "movl $.LC0 - 8 (%ebp) только перезапишет {-8,-7,-6,-5} (%ebp)),
Я сожалею, но я полностью смущен механизма, а также ассемблерного кода...
Большое спасибо за Вашу справку.
Blazeds - это библиотека с открытым исходным кодом, созданная Adobe. Вы можете использовать его, чтобы позвонить в Java Services (методы) непосредственно из стороны Flex, без необходимости создавать некоторые веб-сервисы. Есть также другие преимущества, такие как обмен сообщениями, но главное - это тот факт, что упрощает интеграцию Flex / Java.
Интеграция пружины Blazeds - это проект, созданный ребятами Springsource, чтобы использовать файлы конфигурации пружины для настроек Blazeds и для использования модели Spring Programming. Поэтому, если вы используете пружину на стороне подачи и прогибайте на стороне клиента, это очень хорошая идея, чтобы добавить взвешенные и использовать интеграцию пружины / взвешенные.
-121--4482091- A
является указателем на массив символов. P
- это указатель на чар, который происходит, в данном случае, указанным на строку-литерате.
movl $1819043176, -14(%ebp)
movw $111, -10(%ebp)
Инициализирует локальный «привет» на стеке (поэтому он ссылается через EBP
). Поскольку в «Hello» более 4BYTES требуется два инструкции.
movzbl -11(%ebp), %eax
movsbl %al,%eax
Ссылки
A [3]
: процесс двухэтапного процесса из-за ограничения с точки зрения доступа к памяти, на который ссылаются EBP
(мой x86-FU немного ржавый) Отказ
MOVL-8 (% EBP),% EAX
действительно имеет значение P
P указатель.
LC0
Ссылки на «относительную память» местоположение: фиксированное местоположение памяти будет выделено после загрузки программы в память.
MOVSBL% AL,% EAX
означает: «Переместить один байт, снизить» (дать или взять ... Я должен был посмотреть ... Я немного ржавый на этом фронте). AL
представляет собой байт из реестра EAX
.
Я бы предпочел подход к прямому доступу к частным переменным. IMHO методы gettter увеличивают беспорядок.
-121--4167149-BlazeDS - библиотека с открытым исходным кодом, созданная Adobe. Его можно использовать для вызова сервисов (методов) Java непосредственно со стороны Flex без создания некоторых веб-сервисов. Есть и другие преимущества, такие как обмен сообщениями, но главное, что значительно упрощает интеграцию Flex/Java.
Интеграция Spring BlazeDS - это проект, созданный парнями SpringSource для использования файлов конфигурации Spring для настроек BlazeDS и для использования модели программирования Spring. Поэтому при использовании Spring на стороне обслуживания и Flex на стороне клиента рекомендуется добавить BlazeDS и использовать интеграцию Spring/BlazeDS.
-121--4482091-Хотя верно, что массивы не являются указателями, они ведут себя очень аналогично. В обоих случаях компилятор внутренне сохраняет адрес к типизированному элементу, и в обоих случаях может быть один или несколько элементов.
Как в массивах, так и в указателях компилятор вычисляет адрес элемента, на который выполняется индексирование, умножая индекс на размер типа данных и добавляя его к адресу указателя или массива.
Принципиальное различие между указателем и массивами заключается в том, что массив по существу является опорным. Если допустимо инициализировать указатель на значение null или изменить значение, которое хранит указатель, массивы не могут быть null и не могут быть установлены в другие массивы; они являются по существу постоянными указателями, которым нельзя присвоить значение null.
Кроме того, массивы могут быть выделены в стеке, и это невозможно для указателей (хотя указатели могут быть набором на адреса в стеке, но это может стать уродливым).
Получение на языковой стороне этого, поскольку сторона ассемблера уже обрабатывается:
Обратите внимание на это предложение: «Выражение формы A [I] вызывает массив в распаду Указатель, следующий за правилом выше, а затем должен быть подписан так же, как было бы переменную указателя в выражении P [I] (хотя возможная память будет отличаться, - я довольно запутался в этом: поскольку Чтобы указать, тогда почему он означает о «доступах к памяти, будет отличаться?
Это связано с тем, что после того, как распадается, доступ равен для (теперь значения указателя), а также указатель. Но разница Как Это значение указателя попадает в первую очередь. Давайте посмотрим на пример:
char c[1];
char cc;
char *pc = &cc;
Теперь у вас есть массив. Этот массив не принимает никакого хранения, кроме одного CHARK! Есть Ни один указатель не хранится для него. И у вас есть указатель, который указывает на символ. Указатель принимает размер одного адреса, и у вас есть один символ, который E указатель указывает на. Теперь давайте посмотрим, что произойдет для корпуса массива, чтобы получить значение указателя:
c[0] = 'A';
// #1: equivalent: *(c + 0) = 'A';
// #2: => 'c' appears not in address-of or sizeof
// #3: => get address of "c": This is the pointer value P1
Корпус указателя отличается:
pc[0] = 'A';
// #1: equivalent: *(pc + 0) = 'A';
// #2: => pointer value is stored in 'pc'
// #3: => thus: read address stored in 'pc': This is the pointer value P1
, как вы видите, для корпуса массива для получения требуемого значения указателя, где мы добавляем значение индекса ( В этом случае скучно 0
), нам не нужно читать из памяти, потому что адрес массива уже требуется значение указателя. Но для корпуса указателя нам нужен значение указателя, сохраняется в указатере: нам нужен один читал из памяти, чтобы получить этот адрес.
После этого путь равен для обоих:
// #4: add "0 * sizeof(char)" to P1. This is the address P2
// #5: store 'A' to address P2
вот код ассемблера, сгенерированный для массива, и чехол указателя:
add $2, $0, 65 ; write 65 into r2
stb $2, $0, c ; store r2 into address of c
# pointer case follows
ldw $3, $0, pc ; load value stored in pc into r3
add $2, $0, 65 ; write 65 into r2
stb $2, $3, 0 ; store r2 into address loaded to r3
мы можем просто хранить 65
(ASCII для «A»
) по адресу C
C (который будет известен уже при компиляции или сочетании времени, когда он является глобальным). Для корпуса указателя мы сначала придется загрузить адрес, хранящийся в нем в регистр 3
, а затем напишите 65
на этот адрес.