Comparison of C program stack and stack access efficiency

Source: Internet
Author: User

This article mainly discusses the access efficiency of heap and stack in use, and uses macro assembly commands to analyze the access situation for simple judgment.

Lab environment and tools: i686, 32-bit Ubuntu Linux, gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, gdb


Take a short look at the Code:

# Include

Main (){

Char a = 1;

Char c [] = "1234567890 ";

Char * p = "1234567890 ";

A = c [1];

A = p [1];

}

Char s1 [] = "hello ";
Char * s2 = "world ";
The string that s1 points to belongs to the stack, and the string that s2 points to belongs to the heap. (Of course they all belong to Stacks)

Stack address space is allocated when the link is compiled, and the address space in the heap is dynamically applied for and allocated during runtime.

In future access, the array on the stack is faster than the string pointed to by the pointer (such as the heap.


PS: the heap space is dynamically applied for when the program runs. The system maintains a linked list about idle areas, from small to large, by capacity, and finds the first qualified space (greater than or equal to the required space). How can I delete a deletion? How can I know the number of deleted objects? This size is recorded by the system. It is not a problem. Only free () and delete () can be used. If the number of applications is small, unfortunately it is not suitable. If the number of allocated parts is small, the system will release them to avoid waste.




Macro assembly Command Execution Process:

Breakpoint 1, main () at efficiencyOfStorage. c: 4

4 char a = 1;

1: x/I $ pc

=> 0x8048419 : Movb $0x1, 0x10 (% esp)

5 char c [] = "1234567890 ";

0x804841e : Movl $0x34333231,0x11 (% esp)

Zero x 8048426 : Movl $0x38373635,0x15 (% esp)

0x804842e : Movw $0x3039,0x19 (% esp)

Zero x 8048435 : Movb $0x0, 0x1b (% esp)

6 char * p = "1234567890 ";

0x804843a : Movl $0x8048540, 0xc (% esp)

7 a = c [1];

Zero x 8048442 : Movzbl 0x12 (% esp), % eax

Zero x 8048447 : Mov % al, 0x10 (% esp)

8 a = p [1];

0x804844b : Mov 0xc (% esp), % eax

0x804844f : Movzbl 0x1 (% eax), % eax

Zero x 8048453 : Mov % al, 0x10 (% esp)

10}

Zero x 8048457 : Mov 0x1c (% esp), % edx

0x804845b : Xor % gs: 0x14, % edx

Zero x 8048462 : Je

Zero x 8048469

Zero x 8048464 : Call

0x8048320 <__stack_chk_fail @ plt>

Zero x 8048469 : Leave

0x804846a : Ret

(According to the sequence of variable Declaration, we can see that the offset address in linux increases)

First, it is a character array, and the digit 0-9 is converted into an ascii code 0x30-0x39.


Char c [] = "1234567890 ";

0x804841e : Movl $0x34333231,0x11 (% esp)

Zero x 8048426 : Movl $0x38373635,0x15 (% esp)

0x804842e : Movw $0x3039,0x19 (% esp)

Zero x 8048435 : Movb $0x0, 0x1b (% esp)

The entire array c, including the Terminator, should occupy 11 address spaces (which can be verified by sizeof), from 0x11 to 0x1b.

In the small-end mode, the character array "01234567890" is arranged from the low address 0x11 to the end of 0x1b (end character ascii value 0x00 ):

Stack offset address: 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b

Memory content: 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30 0x00

6 char * p = "1234567890 ";

0x804843a : Movl $0x8048540, 0xc (% esp)

The p pointer is directly stored in the stack, and the process of "1234567890" being stored in the stack is omitted.However, this process should be slower than storing it in the stack. The address space in the stack is determined by the compilation link, while the heap is running.

7 a = c [1];

Zero x 8048442 : Movzbl 0x12 (% esp), % eax

Zero x 8048447 : Mov % al, 0x10 (% esp)

Take 0x32 from address 0x12 and pass it to the eax register.


For details about movzbl, the bottom part of this article is that the popular point is to move the (8-bit) byte length value 0x32 to an address bucket with a (32-bit) long length (in this example, eax) register -- at this time, the eax value is 0x00000032 (the first 24 digits should be filled with 0, because "zero", you can be sure that the last eight digits are 0x32)

Mov al saves the 8-bit low eax value 0x32, that is, number 2, to the treasure offset address 0x10 (that is, the address of variable ). Assigned successfully

If you are still interested in these simple assemblies, please move to my Popular Assemblies


8 a = p [1];

0x804844b : Mov 0xc (% esp), % eax

0x804844f : Movzbl 0x1 (% eax), % eax

Zero x 8048453 : Mov % al, 0x10 (% esp)

Move the pointer p stored in the stack offset address 0xc to the eax register.

The second sentence is hard:

Take the pointer from eax, offset 1, read the second character '2' in the string, and set the value corresponding to the (eight-bit) address (0x32, that is, number 2) offset 0x10 (the address of variable ).

Assign a value to a by passing the 8-bit (0x32) in the eax register to 0x10 of the stack offset address.

Assigned successfully



Conclusion: it can be seen that the former directly reads data from the stack to the Register eax, and the latter must read the pointer value first, then we use pointers to find the value of the desired address. According to our knowledge about the computer composition principle, the memory is accessed once more, which is obviously less efficient.

Appendix:

In this article, the so-called "Stack offset address 0x10" and other non-absolute addresses refer to the offset addresses. % esp is a fixed position, and the offset is the offset added to the fixed position.

=> 0x8048456 : Movl $0x38373635,0x25 (% esp)

(Gdb) print $ esp

$2 = (void *) 0xbffff230

(Gdb) si

0x0804845e 5 char c [] = "1234567890 ";

=> 0x804845e : Movw $0x3039,0x29 (% esp)

(Gdb) print $ esp

$3 = (void *) 0xbffff230

0x08048465 5 char c [] = "1234567890 ";

=> 0x8048465 : Movb $0x0, 0x2b (% esp)

(Gdb) print $ esp

$4 = (void *) 0xbffff230

Movzbl:

In AT&T syntax, the format of symbol extensions and zero-extension commands is: basic sections "movs" and "movz" (corresponding to Intel Syntax: movsx and movzx, movzx is zero extension, that is, the high position is supplemented with zero, and movsx is the symbol extension, that is, the high position is supplemented with the symbol bit)

The length of the source operand and the destination operand. Movsbl means movs (from) byte (to) long; movbw means movs (from) byte (to) word; movswl means movs (from) word (to) long. The same applies to movz commands. For example, the command "movsbl % al, % edx" means to extend the content of the al register and place it in the edx register.

Movzx copies the content of the source operand to the destination operand and extends the value 0 to 16 or 32 bits. However, it only applies to unsigned integers.

It is roughly divided into the following three formats:

Movzx 32-bit General Register, 8-bit General Register/memory unit

Movzx 32-bit General Register, 16-bit General Register/memory unit

Movzx 16-bit General Register, 8-bit General Register/memory unit

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.