.BSS如何分割并处理C程序的内存?

发布于 2025-02-11 19:27:44 字数 1954 浏览 3 评论 0原文

我试图理解.bss内存分配和Deallocation背后的逻辑,

我几乎没有尝试理解相同的情况。

我得出的结论是,如果我在代码的全局范围中声明任何变量,因为我的链接器脚本在8个字节中,它正在增加8个字节,

但是当我定义同一范围内的变量时,它是8个字节的。从.bss处理内存,

但是我不理解的是,DealLocation背后的逻辑计算到底是什么?

case1:

#include <stdio.h>

int a;
int b;

int main(void){
        return 0;
}

此代码片段现在为不同的片段生成以下尺寸

   text    data     bss     dec     hex filename
   1418     544      16    1978     7ba a.out

,如果我初始化一个int变量(如这种

情况)2:

#include <stdio.h>

int a = 1;
int b;

int main(void){
        return 0;
}

立即提供以下大小表

   text    data     bss     dec     hex filename
   1418     548      12    1978     7ba a.out

如果我在int varible之前初始化一个char(如the

Case 3),

#include <stdio.h>

char a = 1;
int b;

int main(void){
        return 0;
}

text    data     bss     dec     hex filename
1418     545      12    1978     7ba a.out

这是Case 3的NM -N输出,

0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 D a
0000000000004011 B __bss_start
0000000000004011 D _edata
0000000000004014 b completed.8060
0000000000004018 D __TMC_END__
0000000000004018 B b
0000000000004020 B _end

如果我初始化一个类似于此情况的一个INT变量

一个int变量:

#include <stdio.h>

int a = 1;
char b;

int main(void){
        return 0;
}

,现在显示出

text    data     bss     dec     hex filename
1418     548      4    1978     7ba a.out

如果我初始化一个类似于这种情况的一个int变量

,现在正在显示:

#include <stdio.h>

char a = 1;
char b;

int main(void){
        return 0;
}

它显示了

text    data     bss     dec     hex filename
1418     545      7    1978     7ba a.out

任何人,请帮助我了解这一点吗?

I am trying to understand the logic behind the .bss memory allocation and deallocation

I have few cases which I have tried to understand the same.

I concluded that it is incrementing in the chunks of 8 bytes if I declare any variable in the global scope of the code because of the linker script of mine is having the alignment of 8 bytes

but when I define the variable inside the same scope it is deallocating the memory from the .bss

but exactly what is the logical calculations behind the deallocation is which I do not understand?

case1 :

#include <stdio.h>

int a;
int b;

int main(void){
        return 0;
}

this code snippet generates the below sizes for the different segments

   text    data     bss     dec     hex filename
   1418     544      16    1978     7ba a.out

now if I initialize one int variable like this

case 2:

#include <stdio.h>

int a = 1;
int b;

int main(void){
        return 0;
}

this gives me the following size table

   text    data     bss     dec     hex filename
   1418     548      12    1978     7ba a.out

now if I initialize one char before the int variable like this

case 3:

#include <stdio.h>

char a = 1;
int b;

int main(void){
        return 0;
}

it is showing

text    data     bss     dec     hex filename
1418     545      12    1978     7ba a.out

this is the nm -n output specifically for the case 3

0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 D a
0000000000004011 B __bss_start
0000000000004011 D _edata
0000000000004014 b completed.8060
0000000000004018 D __TMC_END__
0000000000004018 B b
0000000000004020 B _end

now if I initialize one int variable like this

case 4:

#include <stdio.h>

int a = 1;
char b;

int main(void){
        return 0;
}

it is showing

text    data     bss     dec     hex filename
1418     548      4    1978     7ba a.out

now if I initialize one int variable like this

case 5:

#include <stdio.h>

char a = 1;
char b;

int main(void){
        return 0;
}

it is showing

text    data     bss     dec     hex filename
1418     545      7    1978     7ba a.out

anyone please help me to understand this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青瓷清茶倾城歌 2025-02-18 19:27:44

给定类型的符号具有链接器必须荣誉的自然对齐(例如int必须为4个字节对齐)。在给定的部分(例如.bss)中,链接器有一些余地来重新排序符号,以使给定符号的对齐不会导致多余的填充。如果我们有:

char a;
int b;

如果没有重新排序,则负载映射将看起来像:

0000 a
0004 b

,截面长度为8。

通过重新排序:

0000 b
0000 a

和,截面长度为5

请注意,各节的大小为 >向上到一些多个(通常为8个字节)。因此,例如,如果一个部分只有1个数据字节,则该部分的大小将报告为8。

但是,有例外。

更清楚地查看这一点的方法之一就是简化数据:

  1. 我们可以列出任何库或启动代码以降低可执行的大小。

  2. 我们可以使用相对于 first 数据部分的地址(例如的开始> .data

  3. 开始

我创建了一个[Perl]脚本来做到这一点。它具有您的原始测试用例和一些其他测试用例。

特别值得注意的是情况6 ...

以下是脚本的输出。最终表[和讨论]在下面的最终部分中。


案例1:

来源:

int a;
int b;
int _start(void) { return 0; }

命令:nm -n Xfile

0000 B b
0000 B __bss_start
0000 B _edata
0004 B a
0008 B _end

命令:size xfile xfile

   text    data     bss     dec     hex filename
     50       0       8      58      3a xfile

案例2:

source:

int a = 1;
int b;
int _start(void) { return 0; }

命令:命令: NM -N XFILE

0000 D a
0004 B b
0004 B __bss_start
0004 D _edata
0008 B _end

命令:size xfile

   text    data     bss     dec     hex filename
     50       4       4      58      3a xfile

案例3:

来源:

char a = 1;
int b;
int _start(void) { return 0; }

命令:nm -n xfile

0000 D a
0001 B __bss_start
0001 D _edata
0004 B b
0008 B _end

命令:<代码> size xfile

   text    data     bss     dec     hex filename
     50       1       4      55      37 xfile

案例4:

来源:

int a = 1;
char b;
int _start(void) { return 0; }

命令:nm -n xfile

0000 D a
0004 B b
0004 B __bss_start
0004 D _edata
0008 B _end

命令:size xfile xfile

   text    data     bss     dec     hex filename
     50       4       4      58      3a xfile

案例5:

来源:

char a = 1;
char b;
int _start(void) { return 0; }

命令:nm -n xfile

0000 D a
0001 B b
0001 B __bss_start
0001 D _edata
0008 B _end

命令:size xfile

   text    data     bss     dec     hex filename
     50       1       7      58      3a xfile

案例6:

source:

char a;
int b;
char c = 1;
int d = 1;
int _start(void) { return 0; }

命令:nm -n xfile

0000 D d
0004 D c
0005 B __bss_start
0005 D _edata
0008 B b
000C B a
0010 B _end

命令:大小xfile

   text    data     bss     dec     hex filename
     50       5       8      63      3f xfile

最终:

CASE    DATA    BSS     DEFS
1       0       8       int a; int b;
                        00/B/b 00/B/__bss_start 00/B/_edata 04/B/a 08/B/_end
2       4       4       int a = 1; int b;
                        00/D/a 04/B/b 04/B/__bss_start 04/D/_edata 08/B/_end
3       1       4       char a = 1; int b;
                        00/D/a 01/B/__bss_start 01/D/_edata 04/B/b 08/B/_end
4       4       4       int a = 1; char b;
                        00/D/a 04/B/b 04/B/__bss_start 04/D/_edata 08/B/_end
5       1       7       char a = 1; char b;
                        00/D/a 01/B/b 01/B/__bss_start 01/D/_edata 08/B/_end
6       5       8       char a; int b; char c = 1; int d = 1;
                        00/D/d 04/D/c 05/B/__bss_start 05/D/_edata 08/B/b 0C/B/a 10/B/_end

请注意,在情况6中,.data .data长度为5。 .bss是[也] 5。 >)


这是脚本来源:

#!/usr/bin/perl
# bssgen -- generate .bss data
#
# options:
#   "-c" -- use .o instead of executable
#   "-O" -- optimzation level (DEFAULT: 2)
#   "-v" -- output to stdout (DEFAULT: off)

master(@ARGV);
exit(0);

sub master
{
    my(@argv) = @_;

    $opt_c = 0;
    $opt_O = 2;

    $pubfile = "bssgen.txt";
    printf("output to %s\n",$pubfile);
    $xfpub = xfopen(">$pubfile","master");

    optget(\@argv,
        ["c",1],
        ["n",1],
        ["O",1]);

    my($xfsrc) = "bssgen::DATA";
    $xfsrc = \*$xfsrc;

    while ($bf = <$xfsrc>) {
        chomp($bf);

        if ($bf =~ /^\s*$/) {
            dotest();
        }
        else {
            push(@defs,$bf);
        }
    }

    dotest()
        if (@defs > 0);

    final();

    $xfpub = xfclose($xfpub);
}

sub final
{

    prtsct("FINAL:");

    prtsep();

    @prtcol_tabs = (0,8,16,24);

    prtcol("%s","CASE");
    prtcol("%s","DATA");
    prtcol("%s","BSS");
    prtcol("%s","DEFS");
    prtcol();

    $caseno = 0;
    foreach $tst (@tstlist) {
        ++$caseno;

        prtcol("%d",$caseno);
        prtcol("%d",$tst->{tst_data});
        prtcol("%d",$tst->{tst_bss});
        prtcol("%s",$tst->{tst_defs});
        prtcol();

        prtcol("%s");
        prtcol("%s");
        prtcol("%s");

        my($buf);
        my($nmlhs) = $tst->{tst_nm};
        my($base);
        foreach $nm (@$nmlhs) {
            $buf .= " "
                if (defined($buf));
            $buf .= sprintf("%2.2X/%s/%s",
                $nm->{addr},$nm->{typ},$nm->{sym});
        }
        prtcol("%s",$buf);
        prtcol();
    }

    prtsep();
}

sub dotest
{

    prtsct("Case %d:",++$caseno);

    my($root) = "xfile";
    my($sfile) = $root . ".c";
    my($ofile) = $root . ".o";
    my($xfile) = $root;
    my($run) = $root;

    local($xfdst) = xfopen(">$sfile","dotest/sfile");

    prtpub("Source:\n");
    prtsep();
    foreach $bf (@defs) {
        prtcode("%s\n",$bf);
    }
    prtcode("int %s(void) { return 0; }\n",$opt_c ? "main" : "_start");
    prtsep();

    $xfdst = xfclose($xfdst);

    my(@cflags);
    push(@cflags,"-O")
        if ($opt_O);
    push(@cflags,"-c");
    doexec("cc",@cflags,$sfile);

    unless ($opt_c) {
        doexec("ld","-o",$xfile,$ofile);
        $run = $xfile;
    }
    else {
        $run = $ofile;
    }

    my(@nm);
    push(@nm,"-n");
    @nmrhs = grab(0,"nm",@nm,$run);
    my($base);
    my(@nmlhs);
    prtsep();
    foreach $nm (@nmrhs) {
        chomp($nm);

        my($addr,$typ,$sym) = split(" ",$nm);
        next if ($typ eq "T");

        $addr = hex("0x$addr");
        $base //= $addr;

        $nm = {};
        $nm->{addr} = $addr - $base;
        $nm->{typ} = $typ;
        $nm->{sym} = $sym;

        prtpub("%4.4X %s %s\n",$nm->{addr},$nm->{typ},$nm->{sym});

        push(@nmlhs,$nm);
    }
    prtsep();

    my(@siz) = grab(1,"size",$run);
    my($txt,$data,$bss) = split(" ",$siz[1]);

    my($tst) = {};
    $tst->{tst_defs} = join(" ",@defs);
    $tst->{tst_data} = $data + 0;
    $tst->{tst_bss} = $bss + 0;;
    $tst->{tst_nm} = \@nmlhs;
    push(@tstlist,$tst);

    unless ($opt_k) {
        unlink($sfile);
        unlink($ofile);
        unlink($xfile);
    }

    undef(@defs);
}

sub xfopen
{
    my($file,$who) = @_;
    my($xf);

    open($xf,$file) or
        die("xfopen: unable to open '$file' -- $!\n");

    $xf;
}

sub xfclose
{
    my($xf) = @_;

    close($xf);
    undef($xf);

    $xf;
}

sub grab
{
    my($vflg,@argv) = @_;
    my($cmd,@cmd);

    $cmd = $argv[0];

    prtpub("\n");
    $cmd = join(" ",@argv);
    prtpub("Command: `%s`\n",$cmd);

    @cmd = (`$cmd`);

    prtsep()
        if ($vflg);
    foreach $cmd (@cmd) {
        chomp($cmd);
        prtpub("%s\n",$cmd)
            if ($vflg);
    }
    prtsep()
        if ($vflg);

    @cmd;
}

sub doexec
{

    $_ = join(" ",@_);
    system($_);

    $_ = $? >> 8;
    exit($_) if ($_);
}

sub prtsct
{
    my($fmt,$arg) = @_;

    prtpub("\n");
    prtpub("%s\n","-" x 8);

    $fmt = "**" . $fmt . "**\n";

    prtpub($fmt,$arg);

    prtpub("\n");
}

sub prtsep
{

    prtpub("```\n");
}

sub prtcol
{
    my($fmt,$val) = @_;
    my($tabto);

    {
        unless (defined($fmt)) {
            prtpub("%s\n",$prtcol_buf);
            undef($prtcol_buf);
            undef($prtcol_idx);
            last;
        }

        $tabto = $prtcol_tabs[$prtcol_idx++];
        while (length($prtcol_buf) < $tabto) {
            $prtcol_buf .= " ";
        }

        $fmt = sprintf($fmt,$val);
        $prtcol_buf .= $fmt;
    }
}

sub prtpub
{
    my($fmt);

    $fmt = shift(@_);
    printf($xfpub $fmt,@_);
    printf($fmt,@_)
        if ($opt_v);
}

sub prtcode
{
    my($fmt);

    $fmt = shift(@_);
    printf($xfdst $fmt,@_);
    prtpub($fmt,@_);
}

sub optget
{
    my($argv,@opts) = @_;
    my($arg,$opt);
    my($sym,$val);

    @opts = sort({ $b->[0] cmp $a->[0]} @opts);

    while (@$argv > 0) {
        $arg = $argv->[0];
        last unless ($arg =~ s/^-//);

        shift(@$argv);

        foreach $opt (@opts) {
            my($sym,$dft) = @$opt;

            if ($arg =~ /^$sym(.*)$/) {
                $val = $1;

                {
                    last if ($val =~ s/^=//);
                    last if ($val ne "");
                    $val = $dft;
                }

                ${"opt_" . $sym} = $val;

                last;
            }
        }
    }

    foreach $opt (@opts) {
        my($sym,$dft) = @$opt;
        $sym = "opt_" . $sym;
        ###printf("optget: DEBUG_CAE %s %s\n",$sym,$sym);
    }
}

package bssgen;
__DATA__
int a;
int b;

int a = 1;
int b;

char a = 1;
int b;

int a = 1;
char b;

char a = 1;
char b;

char a;
int b;
char c = 1;
int d = 1;

Symbols of a given type have a natural alignment that the linker must honor (e.g. int must be 4 byte aligned). Within a given section (e.g. .bss), the linker has some leeway to reorder the symbols so that the alignment of a given symbol doesn't cause excess padding. If we have:

char a;
int b;

Without the reordering, the load map would look like:

0000 a
0004 b

And, the section length would be 8.

With reordering:

0000 b
0000 a

And, the section length would be 5

Note that the size of the sections is aligned upward to some multiple (usually 8 bytes). So, for example, if a section has only 1 byte of data, the section size will be reported as 8.

But, there are exceptions.

One of the ways to see this more clearly is to simplify the data:

  1. We can elide any libraries or startup code to reduce the executable size.

  2. We can use addresses relative to the start of the first data section (e.g. start of .data)

  3. Combine results from all cases into a single table

I've created a [perl] script to do that. It has your original test cases and some additional ones.

Of particular note is case 6 ...

Below is the output of the script. The final table [and discussion] is in the FINAL section below.


Case 1:

Source:

int a;
int b;
int _start(void) { return 0; }

Command: nm -n xfile

0000 B b
0000 B __bss_start
0000 B _edata
0004 B a
0008 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       0       8      58      3a xfile

Case 2:

Source:

int a = 1;
int b;
int _start(void) { return 0; }

Command: nm -n xfile

0000 D a
0004 B b
0004 B __bss_start
0004 D _edata
0008 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       4       4      58      3a xfile

Case 3:

Source:

char a = 1;
int b;
int _start(void) { return 0; }

Command: nm -n xfile

0000 D a
0001 B __bss_start
0001 D _edata
0004 B b
0008 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       1       4      55      37 xfile

Case 4:

Source:

int a = 1;
char b;
int _start(void) { return 0; }

Command: nm -n xfile

0000 D a
0004 B b
0004 B __bss_start
0004 D _edata
0008 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       4       4      58      3a xfile

Case 5:

Source:

char a = 1;
char b;
int _start(void) { return 0; }

Command: nm -n xfile

0000 D a
0001 B b
0001 B __bss_start
0001 D _edata
0008 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       1       7      58      3a xfile

Case 6:

Source:

char a;
int b;
char c = 1;
int d = 1;
int _start(void) { return 0; }

Command: nm -n xfile

0000 D d
0004 D c
0005 B __bss_start
0005 D _edata
0008 B b
000C B a
0010 B _end

Command: size xfile

   text    data     bss     dec     hex filename
     50       5       8      63      3f xfile

FINAL:

CASE    DATA    BSS     DEFS
1       0       8       int a; int b;
                        00/B/b 00/B/__bss_start 00/B/_edata 04/B/a 08/B/_end
2       4       4       int a = 1; int b;
                        00/D/a 04/B/b 04/B/__bss_start 04/D/_edata 08/B/_end
3       1       4       char a = 1; int b;
                        00/D/a 01/B/__bss_start 01/D/_edata 04/B/b 08/B/_end
4       4       4       int a = 1; char b;
                        00/D/a 04/B/b 04/B/__bss_start 04/D/_edata 08/B/_end
5       1       7       char a = 1; char b;
                        00/D/a 01/B/b 01/B/__bss_start 01/D/_edata 08/B/_end
6       5       8       char a; int b; char c = 1; int d = 1;
                        00/D/d 04/D/c 05/B/__bss_start 05/D/_edata 08/B/b 0C/B/a 10/B/_end

Note that in case 6, the .data length is 5. And, the starting address of .bss is [also] 5. But, the lowest .bss address actually used is 8 (for b)


Here is the script source:

#!/usr/bin/perl
# bssgen -- generate .bss data
#
# options:
#   "-c" -- use .o instead of executable
#   "-O" -- optimzation level (DEFAULT: 2)
#   "-v" -- output to stdout (DEFAULT: off)

master(@ARGV);
exit(0);

sub master
{
    my(@argv) = @_;

    $opt_c = 0;
    $opt_O = 2;

    $pubfile = "bssgen.txt";
    printf("output to %s\n",$pubfile);
    $xfpub = xfopen(">$pubfile","master");

    optget(\@argv,
        ["c",1],
        ["n",1],
        ["O",1]);

    my($xfsrc) = "bssgen::DATA";
    $xfsrc = \*$xfsrc;

    while ($bf = <$xfsrc>) {
        chomp($bf);

        if ($bf =~ /^\s*$/) {
            dotest();
        }
        else {
            push(@defs,$bf);
        }
    }

    dotest()
        if (@defs > 0);

    final();

    $xfpub = xfclose($xfpub);
}

sub final
{

    prtsct("FINAL:");

    prtsep();

    @prtcol_tabs = (0,8,16,24);

    prtcol("%s","CASE");
    prtcol("%s","DATA");
    prtcol("%s","BSS");
    prtcol("%s","DEFS");
    prtcol();

    $caseno = 0;
    foreach $tst (@tstlist) {
        ++$caseno;

        prtcol("%d",$caseno);
        prtcol("%d",$tst->{tst_data});
        prtcol("%d",$tst->{tst_bss});
        prtcol("%s",$tst->{tst_defs});
        prtcol();

        prtcol("%s");
        prtcol("%s");
        prtcol("%s");

        my($buf);
        my($nmlhs) = $tst->{tst_nm};
        my($base);
        foreach $nm (@$nmlhs) {
            $buf .= " "
                if (defined($buf));
            $buf .= sprintf("%2.2X/%s/%s",
                $nm->{addr},$nm->{typ},$nm->{sym});
        }
        prtcol("%s",$buf);
        prtcol();
    }

    prtsep();
}

sub dotest
{

    prtsct("Case %d:",++$caseno);

    my($root) = "xfile";
    my($sfile) = $root . ".c";
    my($ofile) = $root . ".o";
    my($xfile) = $root;
    my($run) = $root;

    local($xfdst) = xfopen(">$sfile","dotest/sfile");

    prtpub("Source:\n");
    prtsep();
    foreach $bf (@defs) {
        prtcode("%s\n",$bf);
    }
    prtcode("int %s(void) { return 0; }\n",$opt_c ? "main" : "_start");
    prtsep();

    $xfdst = xfclose($xfdst);

    my(@cflags);
    push(@cflags,"-O")
        if ($opt_O);
    push(@cflags,"-c");
    doexec("cc",@cflags,$sfile);

    unless ($opt_c) {
        doexec("ld","-o",$xfile,$ofile);
        $run = $xfile;
    }
    else {
        $run = $ofile;
    }

    my(@nm);
    push(@nm,"-n");
    @nmrhs = grab(0,"nm",@nm,$run);
    my($base);
    my(@nmlhs);
    prtsep();
    foreach $nm (@nmrhs) {
        chomp($nm);

        my($addr,$typ,$sym) = split(" ",$nm);
        next if ($typ eq "T");

        $addr = hex("0x$addr");
        $base //= $addr;

        $nm = {};
        $nm->{addr} = $addr - $base;
        $nm->{typ} = $typ;
        $nm->{sym} = $sym;

        prtpub("%4.4X %s %s\n",$nm->{addr},$nm->{typ},$nm->{sym});

        push(@nmlhs,$nm);
    }
    prtsep();

    my(@siz) = grab(1,"size",$run);
    my($txt,$data,$bss) = split(" ",$siz[1]);

    my($tst) = {};
    $tst->{tst_defs} = join(" ",@defs);
    $tst->{tst_data} = $data + 0;
    $tst->{tst_bss} = $bss + 0;;
    $tst->{tst_nm} = \@nmlhs;
    push(@tstlist,$tst);

    unless ($opt_k) {
        unlink($sfile);
        unlink($ofile);
        unlink($xfile);
    }

    undef(@defs);
}

sub xfopen
{
    my($file,$who) = @_;
    my($xf);

    open($xf,$file) or
        die("xfopen: unable to open '$file' -- $!\n");

    $xf;
}

sub xfclose
{
    my($xf) = @_;

    close($xf);
    undef($xf);

    $xf;
}

sub grab
{
    my($vflg,@argv) = @_;
    my($cmd,@cmd);

    $cmd = $argv[0];

    prtpub("\n");
    $cmd = join(" ",@argv);
    prtpub("Command: `%s`\n",$cmd);

    @cmd = (`$cmd`);

    prtsep()
        if ($vflg);
    foreach $cmd (@cmd) {
        chomp($cmd);
        prtpub("%s\n",$cmd)
            if ($vflg);
    }
    prtsep()
        if ($vflg);

    @cmd;
}

sub doexec
{

    $_ = join(" ",@_);
    system($_);

    $_ = $? >> 8;
    exit($_) if ($_);
}

sub prtsct
{
    my($fmt,$arg) = @_;

    prtpub("\n");
    prtpub("%s\n","-" x 8);

    $fmt = "**" . $fmt . "**\n";

    prtpub($fmt,$arg);

    prtpub("\n");
}

sub prtsep
{

    prtpub("```\n");
}

sub prtcol
{
    my($fmt,$val) = @_;
    my($tabto);

    {
        unless (defined($fmt)) {
            prtpub("%s\n",$prtcol_buf);
            undef($prtcol_buf);
            undef($prtcol_idx);
            last;
        }

        $tabto = $prtcol_tabs[$prtcol_idx++];
        while (length($prtcol_buf) < $tabto) {
            $prtcol_buf .= " ";
        }

        $fmt = sprintf($fmt,$val);
        $prtcol_buf .= $fmt;
    }
}

sub prtpub
{
    my($fmt);

    $fmt = shift(@_);
    printf($xfpub $fmt,@_);
    printf($fmt,@_)
        if ($opt_v);
}

sub prtcode
{
    my($fmt);

    $fmt = shift(@_);
    printf($xfdst $fmt,@_);
    prtpub($fmt,@_);
}

sub optget
{
    my($argv,@opts) = @_;
    my($arg,$opt);
    my($sym,$val);

    @opts = sort({ $b->[0] cmp $a->[0]} @opts);

    while (@$argv > 0) {
        $arg = $argv->[0];
        last unless ($arg =~ s/^-//);

        shift(@$argv);

        foreach $opt (@opts) {
            my($sym,$dft) = @$opt;

            if ($arg =~ /^$sym(.*)$/) {
                $val = $1;

                {
                    last if ($val =~ s/^=//);
                    last if ($val ne "");
                    $val = $dft;
                }

                ${"opt_" . $sym} = $val;

                last;
            }
        }
    }

    foreach $opt (@opts) {
        my($sym,$dft) = @$opt;
        $sym = "opt_" . $sym;
        ###printf("optget: DEBUG_CAE %s %s\n",$sym,$sym);
    }
}

package bssgen;
__DATA__
int a;
int b;

int a = 1;
int b;

char a = 1;
int b;

int a = 1;
char b;

char a = 1;
char b;

char a;
int b;
char c = 1;
int d = 1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文