【问题标题】:Calculate Number of Instructions in Assembly File计算汇编文件中的指令数
【发布时间】:2016-06-15 00:10:43
【问题描述】:

我有一个在 SPARC T1 RTL 代码上运行的 SPARC 汇编文件(通过汇编程序将其转换为内存映像)。但我需要知道 RTL 正在执行多少条指令。无法手动计算文件中的指令数。如果您能向我展示一种方法,我将不胜感激......

由于文件很大,我附上 Dropbox 链接: https://dl.dropboxusercontent.com/u/48635184/exu_muldiv.s

但这里是前几行代码:

    /***********************************************************************
 * Name:    exu_muldiv.s
 * Date:    April 23, 2003
 *
 *  Description: Execute Mulx, Mulscc, Smul, Smulcc, Umul, Umulcc,
 *  Sdiv, Sdivcc, Sdivx, Udiv, Udivcc, Udivx with interesting data 
 *  patterns in multiple threads. Also play with delay slots and
 *  intermixed mul and div operations.
 *
 *  This test depends on SAS for result checking.    
 *
 **********************************************************************/

! be sure to update when adding cases...
#define NUM_MUL_CASES 6
#define NUM_DIV_CASES 4
#define NUM_IMMED_CASES 5    

! for divide by zero cases
#define H_T0_Division_By_Zero
#define My_T0_Division_By_Zero \
rdpr    %tstate, %i1; \
rdpr    %tt, %i1; \
rdpr    %tpc, %i0; \
rdpr    %tnpc, %i1; \
done; \
nop;    

/*******************************************************/    
#include "boot.s"

.global main
main:
th_fork(th_main,%l0)        ! start up to four threads.
    ! All threads do the same thing, but with different data patterns. 
    ! No need to run more than one core.
th_main_0:
    setx    mul_data_t0,%g7,%g1
        ba  all_threads1
    nop

th_main_1:
        setx    mul_data_t1,%g7,%g1
    ba  all_threads1
    nop

th_main_2:
    setx    mul_data_t2,%g7,%g1
        ba  all_threads1
    nop

th_main_3:
    setx    mul_data_t3,%g7,%g1
    ba  all_threads1
    nop

all_threads1:       
    !*************************************************************
    ! Operand2 as a register:    MULX, UMUL, SMUL, UMULcc, SMULcc
    !*************************************************************
    add %g0,NUM_MUL_CASES,%g2
    mova    %icc,%g1,%g3        ! keep the multiply operand address handy

mul_loop1:
    ldx [%g1],%l1
    ldx [%g1+8],%l2
    wr  %g0,%g0,%ccr        ! ccr clear

    mulx    %l1,%l2,%l4
    umul    %l1,%l2,%l5
    rd  %y,%i1          ! be sure SAS looks at Y-reg
    smul    %l1,%l2,%l6
    rd  %y,%i1

        wr  %g0,%g0,%ccr        ! clear ccr     
    umulcc  %l1,%l2,%l7     
    rd  %y,%i1
        wr  %g0,%g0,%ccr        
    smulcc  %l1,%l2,%l6     
    rd  %y,%i1

        wr  %g0,0xff,%ccr       ! set ccr. Should not matter.       
    umulcc  %l1,%l2,%l7     
    rd  %y,%i1
        wr  %g0,0xff,%ccr       
    smulcc  %l1,%l2,%l6     
    rd  %y,%i1    

    sub %g2,0x1,%g2
    brnz,pt %g2,mul_loop1
    add %g1,0x10,%g1        ! move operand pointer

    !**********************************
    ! Operand2 as a register:    MULScc
    !**********************************
#ifndef MULSCC_BUGS    
        mova    %icc,%g3,%g1        ! same ops as mul_loop1
    add %g0,NUM_MUL_CASES,%g2       
mulscc_1:
    wr  %g0,%g0,%ccr        ! ccr clear    
    ldx [%g1],%l1
    ldx [%g1+8],%l2
    wr  %l1,0,%y        ! lower bits of multiplier into Y-reg
    rd  %y,%l0          ! for sas debug
    srl %l1,0,%l1       ! clear rs1 upper
    srl %l2,0,%l2       ! clear rs2 upper
    mulx    %l1,%l2,%l4     ! save for later compare
    add %g0,0,%l1       ! clear rs1 (product upper) completely

    add %g0,32,%l3      ! bit position counter
mulscc_2:   
    sub %l3,1,%l3
    mulscc  %l1,%l2,%l1
    brgez,pt %l3,mulscc_2  
    nop 

    sllx    %l1,33,%l1      ! product upper
    rd  %y,%l3          ! product lower
    or  %l1,%l3,%l3     ! full product should be equal to mulx
    subcc   %l3,%l4,%l5
    tnz T_BAD_TRAP
    nop

    sub %g2,0x1,%g2
    brnz,pt %g2,mulscc_1
    add %g1,0x10,%g1        ! move operand pointer
#endif    

    !****************************************
    ! Operand2 as a register:    SDIVX, UDIVX
    !****************************************
    rdth_id             ! get thid in %o1
    cmp %o1,0
    be  th_divx_0
    cmp %o1,1
    be  th_divx_1
    cmp %o1,2
    be  th_divx_2
    nop
    ba  th_divx_3       ! if there are more than 4 threads...
    nop

th_divx_0:
    setx    divx_data_t0,%g7,%g1
        ba  all_threads2
    nop

th_divx_1:
    setx    divx_data_t1,%g7,%g1
        ba  all_threads2
    nop

th_divx_2:
    setx    divx_data_t2,%g7,%g1
        ba  all_threads2
    nop

th_divx_3:
    setx    divx_data_t3,%g7,%g1  
    ba  all_threads2
    nop

all_threads2:       
    add %g0,NUM_DIV_CASES,%g2

divx_loop1:
    ldx [%g1],%l1
    ldx [%g1+8],%l2
    wr  %g0,%g0,%ccr        ! ccr clear 

    sdivx   %l1,%l2,%l3
    udivx   %l1,%l2,%l4
    sdivx   %l2,%l1,%l5     ! use each operand as divisor and dividend
    udivx   %l2,%l1,%l6

    sub %g2,0x1,%g2
    brnz,pt %g2,divx_loop1
    add %g1,0x10,%g1        ! move operand pointer 

【问题讨论】:

  • 我想知道你是否可以在某个模拟器中运行它,是否可以破解模拟器来给你运行指令的数量(如果这没有意义,请原谅我)
  • 所以你需要动态指令计数(执行的指令总数),而不是静态 insn 计数(文件中的总 insn;循环内的 insn 仍然只计算一次。即代码大小)?
  • @Leo,你说得对,我在 VCS Simulator 上运行它,但我只是不知道如何/在哪里做。
  • @PeterCordes,静态指令可以让我很好地了解程序的大小,但是什么是计算指令总数(静态)的有效方法,然后我可以简单地将它与获取文件中需要执行的总指令的循环数。
  • 您的一些指令在循环之外,所以这只是一个粗略的近似值,只有在您知道每个循环的迭代次数时才有效。无论如何,IDK如何。也许组装它并计算字节数,因为 SPARC 是具有固定大小指令的 RISC 机器。或者 assemble->disassemble 和 count lines(这会从 cmets 和标签中删除源代码行数)。

标签: assembly


【解决方案1】:

我认为,一般而言,了解动态指令计数的唯一方法是在计算指令的检测环境中实际运行代码。 (例如,模拟器或带有性能计数器的 CPU)。

我认为一个能够可靠地计算另一个程序将运行的指令数量的程序将等同于解决Halting Problem

在许多实际情况下,循环后的分支不会依赖于循环计算的结果。如果循环结束条件很简单,比如将计数器递增到某个限制,那么只需将迭代次数 * 每迭代指令数加到总数中即可。

不是一个简单的问题;复杂性可能类似于编写一个以 asm 作为输入的优化编译器。您需要分析数据流来确定将采用哪些分支,而对于某些代码,您只需模拟发生的情况。

你最好的选择几乎肯定是像@Leo 所说的那样找到一个模拟器/模拟器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多