代码之家  ›  专栏  ›  技术社区  ›  psihodelia

Bash-如何计算指令数?

  •  3
  • psihodelia  · 技术社区  · 14 年前

    我有很多*.s程序集文件。我想数一数它们包含了多少指令。例如,数一数 骡子 我做的说明:

    cat *.s | grep -P '\t'"mul" | wc -l
    

    这给了我一个所有mul指令的复合数。

    我希望输出如下:

    mul: 893
    add: 12054
    sub: 2356
    ...
    

    问题是目标平台不支持指令表。每个目标平台都有不同的指令集。支持的指令必须从现有的汇编文件中推导出来。我只能在没有Perl/Python foundry的情况下在Bash中完成吗?

    5 回复  |  直到 14 年前
        1
  •  5
  •   Brent Newey    14 年前

    你可以像这样得到它们:

    grep -hP '^[ \t]+[a-z]*' *.s | sed 's/^[ \t]\+\([a-z]*\).*/\1/' | sort | uniq -c
    

    编辑:我将此更改为使用SiegeX提供的示例。

    输出:

    1 call
    6 mov
    1 push
    1 ret
    2 syscall
    2 xor
    
        2
  •  5
  •   SiegeX    14 年前

    假设您的指令都是使用空格从其他代码缩进的(tab是OK),那么 awk 1-衬垫将工作:

    awk '/^[[:space:]]+/{a[$1]++}END{for(op in a){print op,a[op]}}' /path/to/*.s
    

    输入

    $ cat asm.s
    section .text
    global _start, write
    write:
      mov al,1 ;write syscall
      syscall
      ret
    _start:
      mov rax,0x0a68732f6e69622f
      push rax
      xor rax,rax
      mov rsi,rsp
      mov rdi,1
      mov rdx,8
      call write
    
    exit: ; just exit not a function
      xor rax,rax
      mov rax,60
      syscall
    

    输出

    $ awk '/^[[:space:]]+/{a[$1]++}END{for(op in a){print op,a[op]}}' ./*.s
    push 1
    xor 2
    ret 1
    mov 6
    syscall 2
    call 1
    
        3
  •  1
  •   Dennis Williamson    14 年前

    没有任何外部实用程序的Bash 4:

    declare -A c;while IFS=$'\n' read -r t;do [[ ! $t =~ ^[[:space:]] ]] && continue;w=($t);((c[${w[0]}]++));done<asm.s;for op in ${!c[@]};do echo $op ${c[$op]};done
    

    若要执行多个文件,请将 while 循环 for f in *.s 与while循环 done 这样地: done < "$f" 或者做一会儿 完成 这样地: done < <(cat *.s) 而不是 for f .

    略短一点,以计算每行上的第一个单词,而不考虑缩进:

    declare -A c;while read -ra t;do [[ $t ]]&&((c[${t[0]}]++));done<asm.s;for op in ${!c[@]};do echo $op ${c[$op]};done
    

    不过,这比其他答案要长。

        4
  •  0
  •   sorpigal    14 年前

    只是为了见鬼,SiegeX用Perl给出的awk答案

    perl -n '/^\s+(\w+)/&&$a{$1}++;END{print map{"$_ $a{$_}\n"}keys%a}' ./*.s
    

    因为“你能做的任何事我都能以更接近线噪声的方式来做”(-:

        5
  •  0
  •   micronegor    14 年前

    grep-Eo'\w+'/source.file | uniq-c