美文网首页c/c++
11章 运行库

11章 运行库

作者: my_passion | 来源:发表于2022-07-10 17:08 被阅读0次

1 入口点 (Entry Point) 和 程序初始化

    程序入口 真的是 main 函数吗 ? 不是

    (1) 程序运行步骤
        
        1) OS 创建 进程 -> 控制权转交 给 `入口点: 运行库` 中 `某个入口函数`
        
        2) 入口点 对 运行库 和 程序运行环境 `初始化`
        
            [1] globalVar 构造
            
            [2] 堆 
                可放心 malloc/new
                
            [3] 栈
                环境变量 / argv / argc 入栈 
                    main 的 2 个 para (argc / argv) 被正确传了进来
                
            [4] I/O
                可放心用 scanf/printf
                
            [5] 线程
            
        3) 调用 main  
        
        4) 记录 main 的 returnValue 
        
        -> `反向清理` -> 系统调用 `结束进程`
            
    (2) 入口函数 如何实现?
        
        Linux 下 Glibc 入口函数 _start
            
        伪代码
            void _start()
            {
                %ebp = 0;
                
                int argc = pop from stack
                
                char** argv = top of stack; // esp
                
                __libc_start_main(main, argc, argv, __lib_csu_init, __libc_csu_fini, edx, top of stack)
            }

2 C/C++ 运行库

    运行库: 入口函数 及其 所依赖的函数 + 标准库函数 的 函数集合      
    
    ANSI C 标准库: 24 个 C 头文件 组成 -> 轻量

(1) 变长参数

机制: 得益于 C 语言默认的 cdecl 调用惯例自右向左压栈 传递 方式

实现思路: 4 个

    va_list // va_list ap;
        1) 是 `指针`, 用于指向 `各变参`
        2) 类型不明 => 最佳选择为 void* 或 char*

        #define va_list char*

    va_start(ap, lastNamedPara)
        将 `va_list 指针 ap` 指向 `第1个变参`
        
        #define va_start(ap, arg) ( ap = (va_list)&arg + sizeof(arg) )
    
    va_arg(ap, type) // type currentUndefinedPara = va_arg(ap, type)
        return `type 已知 的 当前变参值` + 移 ap 到 next 变参
        
        #define va_arg(ap, type) ( *(type*)( (ap += sizeof(type) ) - sizeof(type) )  )
        
    va_end(ap) 
        指针 ap 清 0
        
        #define va_end(ap) (ap = (va_list)0 )
    
    变参指针 ap
        依次指向 各 变参 
        
        1)  `必须用 va_start 初始化` 1 次, lastNamedPara 必须是 `最后1个 具名 arg`
        
        2) 被 va_arg 移到 `type 已知` 的 `本变参` 的 `next 变参` 位置
int sum(unsigned num, ...)
{
    int* p = &num + 1;
    int ret = 0;
    while(num--)
        ret += *p++;
    return ret;
}

int n = sum(3, 16, 38, 53);
环境变量 和 argv arvc 在 栈中布局.jpg FILE 结构、fd、内核对象.jpg 变长参数: 栈上分布 + 4 个宏.jpg TLS.jpg

相关文章

网友评论

    本文标题:11章 运行库

    本文链接:https://www.haomeiwen.com/subject/epgwbrtx.html