1. Writing the C program ch03_05_01.c
/* * This program constructs a structure TestStruct with members of different lengths. * It sums the structure members using both C functions and assembly functions to verify the correctness of the assembly code. * The focus is on the Pad8 member, which does not participate in calculations, but serves to align data and improve program execution speed. */#include<stdio.h>#include<inttypes.h>/* This header file is used to specify fixed-size variables, see https://mp.weixin.qq.com/s/8p_fbZfuLo1dkpMmDS_9Hg */struct TestStruct{int8_t Val8;int8_t Pad8;int16_t Val16;int32_t Val32;int64_t Val64;};extern int64_t CalcTestStructSum_(const struct TestStruct* ts);int64_t CalcTestStructSumC(const struct TestStruct* ts){return ts->Val8+ts->Val16+ts->Val32+ts->Val64;}int main(void){struct TestStruct ts; ts.Val8=-100; ts.Pad8=0; ts.Val16=2000; ts.Val32=-300000; ts.Val64=40000000000;int64_t sum1=CalcTestStructSumC(&ts);int64_t sum2=CalcTestStructSum_(&ts);printf("ts.Val8=%d\n",ts.Val8);printf("ts.Val16=%d\n",ts.Val16);printf("ts.Val32=%d\n",ts.Val32);printf("ts.Val64=%ld\n",ts.Val64);printf("\n");printf("sum1=%ld\n",sum1);printf("sum2=%ld\n",sum2);return 0;}
2. Writing the assembly code ch03_05_02.asm
The C program passes the memory address of the structure pointer to the rdi register. # The gas assembler does not support address offset syntax like [rcx+TestStruct.Val8] as in masm, so the offset values must be written manually. # The int8_t type is 1 byte, int16_t is 2 bytes, int32_t is 4 bytes, and int64_t is 8 bytes. # Through assembly language, we can better understand why the Pad8 member, which does not participate in calculations, is added when defining the TestStruct structure in C. # In AT&T assembly format, 2(%rdi) indicates an offset of 2 bytes from the memory address pointed to by rdi. Since Val8 occupies only 1 byte, an offset of 2 bytes cannot point to the starting address of the Val16 member, which increases computational complexity. Therefore, the Pad8 member is added to optimize program execution speed. .text.globl CalcTestStructSum_CalcTestStructSum_: movsbq (%rdi),%rax movswq 2(%rdi),%rcx addq %rcx,%rax movslq 4(%rdi),%rcx addq %rcx,%rax movq 8(%rdi),%rcx addq %rcx,%rax ret
3. Writing the Makefile and running it
ch03_05_0102:ch03_05_01.c ch03_05_02.o gcc -no-pie ch03_05_01.c ch03_05_02.o -o ch03_05_0102ch03_05_02.o:ch03_05_02.asm as ch03_05_02.asm -o ch03_05_02.o
4. The results are as follows
ts.Val8=-100ts.Val16=2000ts.Val32=-300000ts.Val64=40000000000sum1=39999701900sum2=39999701900