[Understanding C language pointers through assembly language]

Deduce C language pointers from assembly

Assembly derivation C language pointer

Pointer is an important concept and its characteristics in C language. As mentioned in the previous chapter, assembly language is to allow developers to better understand machine language, and to deal with program errors through assembly language.
The machine language is executed by the CPU, and there are various registers inside the CPU with different functions. The purpose is to promote the normal operation of the program, so it can be understood that the assembly language is operating the CPU. The C language is the purest abstraction of assembly language (because assembly language is easier to understand than machine language, but it is relatively complicated). In layman's terms, C language is translating assembly language, so understanding assembly language can help us understand more Good understanding of pointers in C language.

First of all, we have such a requirement that we call another method in the first method, and at the same time, we need to pass the variable in the method, so that when the other method modifies the variable, the first method can perceive the second method. A method modifies the variable, what should I do? We know that if a program wants to run, the program must be loaded into the memory first, and the instruction method in the operation program needs to be pushed into the stack of the program, and the private data of the program code is stored in the stack, then these data Where do you come from? There is no doubt that the data is in memory, where is it stored in memory? There is a corresponding address in the memory, so as long as we have the memory address corresponding to the data, we can operate the data. So for the above requirements, we only need to pass the memory address of the variable to the second method, then the first method can also perceive the operation of the variable by the second method, because the first method already has The memory address of the variable! Next, two assembly instructions are introduced: leaf, and ();
leaf instruction: get variable address
(): send the address in () to the address bus for operation, simply understand it as operating the variable in the address after
introducing the above After requirements and basic information, let's look at an example of C language

#include <stdio.h>

int sum(int *p){
  *p = 10;
  return 10;
}
 
int main()
{
    /* 我的第一个 C 程序 */
    int a = 3;
    int f = sum(&a);
    return 0;
}

This code is easy to understand. A variable a is set, then the sum method is called, and the address of a is passed in. We compile our C file by gcc -m32 -S demo.c (some unnecessary files have been omitted)

	.file	"demo.c"
	.text
	.globl	sum
	.type	sum, @function
#函数sum
sum:
.LFB0:
	pushl	%ebp
	movl	%esp, %ebp
	#调用方法之后,将刚才放入esp的值取出来放入eax中
	movl	8(%ebp), %eax
	然后将eax中的值当作地址送入地址总线,操作该地址所对应的变量
	movl	$10, (%eax)
	movl	$10, %eax
	popl	%ebp
	ret
	.cfi_endproc
.LFE0:
	.size	sum, .-sum
	.globl	main
	.type	main, @function
#程序入口main
main:
.LFB1:
	pushl	%ebp
	movl	%esp, %ebp
	#开辟20个字节的空间
	subl	$20, %esp
	将3压入离栈底-8个字节的位置(因为栈底在高地址,栈顶在低地址)
	movl	$3, -8(%ebp)
	取-8(%ebp)中的地址,并将其放入到eax寄存器中,还记得上面说的吗,leal就是取地址操作
	leal	-8(%ebp), %eax
	将eax的值放入到esp栈底寄存器中,还记得()这个操作码,就是将eax的值放入到esp所对应的内存地址中
	movl	%eax, (%esp)
	#调用sum函数,然后在去看上面的sum函数做了什么
	call	sum
	movl	%eax, -4(%ebp)
	movl	$0, %eax
	leave
	ret
.LFE1:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
	.section	.note.GNU-stack,"",@progbits

In this assembly code, we focus on .LFB1. I made a simple comment in the above code, and you can see that the memory address of variable 3 is stored in the eax register, and then the address is transmitted through instructions such as leal, () In the sum method, the sum method operates on the memory address of variable 3, so that the change of variable 3 can also be perceived in the main method.
Then we compare it to the C language, isn't the C language & the abstraction of the leal instruction? *Isn't it just an abstraction for ()?

Through the above assembly and C language examples, we have a better understanding of C language pointers.

Guess you like

Origin blog.csdn.net/weixin_44821965/article/details/126333129