MOVL 16(%ebp), %eax /* put long at ebp+16 into eax */
LEAL 16(%ebp), %eax /* add 16 to ebp and store in eax */
MOVQ (%rdx,%rcx,8), %rax /* put qword at rcx*8 + rdx into rax */
LEAQ (%rdx,%rcx,8), %rax /* put value of "rcx*8 + rdx" into rax */
MOVW 5(%bp,%si), %ax /* put word at si + bp + 5 into ax */
LEAW 5(%bp,%si), %ax /* put value of "si + bp + 5" into ax */
MOVQ 16(%rip), %rax /* put qword at rip + 16 into rax */
LEAQ 16(%rip), %rax /* add 16 to instruction pointer and store in rax */
MOVL label(,1), %eax /* put long at label into eax */
LEAL label(,1), %eax /* put the address of the label into eax */
[1]我已经说过,当 array是 long的数组时,表达式 array[i]将从地址 array + i * sizeof(long)加载该值。这是真的,但有一个微妙的地方需要解决。如果我写 C 代码
long x = array[5];
这是 没有,和打字一样
long x = *(array + 5 * sizeof(long));
它似乎是 应该的基础上,我以前的陈述,但它不是。
C 指针加法有一个窍门。假设我有一个指针 p指向类型为 T的值。表达式 p + i does 没有表示“ p处的位置加上 i字节”。相反,表达式 p + i事实上表示“ p处的位置加上 i * sizeof(T)字节”。
这种方法的便利之处在于,要获得“下一个值”,我们只需要编写 p + 1而不是 p + 1 * sizeof(T)。
这意味着 C 代码 long x = array[5];实际上等效于
long x = *(array + 5)
因为 C 会自动将 5乘以 sizeof(long)。
那么,在这个 StackOverflow 问题的上下文中,这一切是如何相关的呢?这意味着当我说“地址 array + i * sizeof(long)”时,我做 没有的意思是“ array + i * sizeof(long)”被解释为一个 C 表达式。为了让我的答案更加明确,我自己正在做 sizeof(long)的乘法运算,但是由于这个原因,这个表达式不应该被读作 C,就像普通的使用 C 语法的数学一样。