This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/processor-SDK-AM335X:在宏调用过程中,汇编器符号表中不提供正向引用标注

Guru**** 2540720 points
Other Parts Discussed in Thread: AM3359

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/567464/compiler-processor-sdk-am335x-forward-referenced-labels-not-available-in-assembler-symbol-table-during-macro-invocation

部件号:processor-SDK-AM335X
主题中讨论的其他部件:AM3359

工具/软件:TI C/C++编译器

clpru版本:2.1 .................4.

在伪操作宏的开发过程中,人们通常会发现有必要使用替换符号函数,例如用于区分常量和装配体标签符号的$isdefed (arg)。 下面的代码显示了在标签"my_label"之前和之后使用的伪操作MOV宏指令。

   MOV      R31,my_label
我的标签:
   MOV      R31,my_label

在MOV pseudo-op中"my_label"之前使用函数$isdefed("my_label")会导致$isdefed("my_label")== 0,而在MOV pseudo-op中,在 "my_label"之后会导致$isdefed("my_label")== 1。 这似乎表明宏扩展是在单次分析程序中进行的。 强大的汇编程序可能希望在第一次分析标签符号,以便在操作代码评估之前获得完整的符号表。

我还注意到$isreg (arg)无法正常工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为了让我了解所有细节,请提供一个可证明此问题的测试案例。  它必须是我可以建立的。  请确保显示所有生成选项的方式与编译器shell (clpru)看到的完全相同。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    George,

            请在下面查找用于识别异常的宏定义。

    随后还可以找到使用的汇编测试代码'mov_macro_trst.ASM'。

    使用的clpru命令行调用是:

    root@debian-8:2.1。4/example#

    ../bin/clpru $build_root/ti-CGT-PRU_MACR.4/example/mov_macro_test.asm 2.1 \

    $build_root/ti-CGT-PRU_PRU.4/example/test_xeno_pruss.c 2.1 \

    --run_linker --ram_model --output_all_sims \

    -i $build_root/ti-CGT-PRU_PRU.4/lib 2.1 \

    2.1 .4/example/mov_macro_test.bin \

    --library=AM3359_PRU.cmd

    ;*********
    ;*宏
    ;*********

    ISREG .MACRO参数,结果
       r31,r30,r29,r28,r27,r26,r25,r24,r23,r22,r21,r20,r19,r18,r17,r16,r15,r14,r13,r12,r11,r10,r9,r8,r8,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21,r21
       r31.b0,r31.b1,r31.b2,R31.b3,R31.b0,R31.b1,R31.b3,r30.b3,r30.b1,r30.b1,r30.b1,r30.b2,r30.b2,r27.b2,r27.b1,r27.b1,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r27.b2,r29.r29.r29.r29.r29.r29.r27.b2,r29.r27.b2,r29.r27.r29.r27.b2,r29.r27.r27.b2,r29.r27.b2,r29.r27.r27.r27.b2,r29.r27.r27.r27.r27.b2,r29.r27.r27.r27.b2,r27.b2,r27.r27.r27.r27.r27.b2,r27.b2,r
       r31.w0,r31.w1,r31.w2,R31.w0,R31.W1,R31.w2,r30.w0,r30.w1,r30.w2,R30.W0,R30.W0,R30.W1,R27.W2.R2.W2.15.R27.W2.R2.W2.W2.R2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.15.R2.W2.W2.15.R26.W2.15.R2.W2.W2.15.R2.W2.15.R26.W2.15.R2.W2.15.R2.W2.W2.15.R2.15.0.、R26.W2.R2.W2.W2.W2.R2.R2.W2.W2.R26.W2.R26.W2.R26.W2.R2.R26.W2.R2.R26.W2.R2.R2.W2.W2.R2.W2.W2.R2.12.0.

       .ASG "",注册

       回路64
          .if ($ismember (reg,int_regs))                      ;从列表中获取下一个reg定义字符串
             如果($symcmp(arg, reg)==0)
                .mmsg "参数字符串是有效的INT寄存器"
                eval 1,结果
                中断
             endif
          endif
       端环

       循环256
          .if ($ismember (reg,byte_regs))                      ;从列表中获取下一个reg定义字符串
             如果($symcmp(arg, reg)==0)
                .mmsg "参数字符串是有效的字节寄存器"
                eval 1,结果
                中断
             endif
          endif
       端环

       回路192
          .if ($ismember (reg,word_regs))                      ;从列表中获取下一个reg定义字符串
             如果($symcmp(arg, reg)==0)
                .mmsg "参数字符串是有效的字寄存器"
                eval 1,结果
                中断
             endif
          endif
       端环

       如果!($symcmp(result,"1")== 0)                      ;报告错误
          .mmsg "ISREG:参数无效寄存器"    
       endif
       
       {\f2 .endm}

    ;******************************************************************
    ;移动寄存器
    ;说明:   加载最多32位常量,13位标签值
    ;             或从'srC'注册到有效的'st'注册表。
    ;******************************************************************
    MOV宏分布,源
       ASG"b",b
       .ASG"w",w
       .ASG 0,is_src_reg
       .ASG 0,is_dst_reg

       ISREG   src,is_src_reg
       ISREG   DST,is_Dst_reg
       如果($symcmp(is_dst_reg,"1")== 0)
          .mmsg "目标参数是有效的符号名称"
          如果$firstch (dst,b)                            ;如果dst是字节注册
             .mmsg "目标reg is byte"
             如果($symcmp(is_src_reg,"1")== 0)             ;如果src是REG
                .mmsg "源是寄存器"    
                和      DST,src,src
             elseif $isdefed (src)                      ;如果src是8k指令地址空间中定义的符号标签
                .mmsg "源是一个符号"
                LDI      DST,src.
             elseif $isname (src)                      ;如果src可以是正向引用的符号标签
                .mmsg "***源代码是正向引用的符号名称"    
                LDI      DST,src.
             elseif $iscons (src)                      ;如果src是const
                .mmsg "源是常量"
                LDI      DST,SRC和0xFF
             否则
                .mmsg "***假定源参数不变"
                LDI      DST,SRC和0xFF
             endif
          elseif $firstch (dst,w)                         ;如果dst是word reg
             .mmsg "目的地注册是单词"
             如果($symcmp(is_src_reg,"1")== 0)             ;如果src是REG
                .mmsg "源是寄存器"    
                和      DST,src,src
             elseif $isdefed (src)                      ;如果src是8k指令地址空间中定义的符号标签
                .mmsg "源是一个符号"
                LDI      DST,src.
             elseif $isname (src)                      ;如果src可以是正向引用的符号标签
                .mmsg "***源代码是正向引用的符号名称"    
                LDI      DST,src.
             elseif $iscons (src)                      ;如果src是const
                .mmsg "源是常量"
                LDI      DST,SRC和0xFFFF
             否则
                .mmsg "***假定源参数不变"
                LDI      DST,SRC和0xFFFF
             endif
          否则                                     ;否则DST为INT REG    
             .mmsg "目的地注册为INT"
             如果($symcmp(is_src_reg,"1")== 0)             ;如果src是REG
                .mmsg "源是寄存器"    
                和      DST,src,src
             elseif $isdefed (src)                      ;如果src是在8k指令地址空间中定义的符号标签
                .mmsg "源是一个符号"    
                LDI      DST,src.
             elseif $isname (src)                      ;如果src可以是正向引用的符号标签
                .mmsg "***源代码是正向引用的符号名称"    
                LDI      DST,src.
             elseif $iscons (src)                      ;如果src是const
                .mmsg "源是常量"
                LDI      DST.W0,SRC和0xFFFF
                LDI      Dst.w2,src >> 16.
             否则
                .mmsg "***假定源参数不变"
                LDI      DST.W0,SRC和0xFFFF
                LDI      Dst.w2,src >> 16.
             endif
          endif
       否则
          .emsg "目标参数无效的预定义寄存器"
       endif
       {\f2 .endm}

    ;*********************************************************

    ; mov_macro_test.asm

    ;*********************************************************

    ;包含定义和宏头文件
       包括"PRU_hardI2C_IET_Interrupt_h.ASM"

       定义"0x100",Shared_RAM
       定义0x10万,DDR_RAM

    标签:
       mmsg "mov_macro_test_v 1.0 (mov_macro_test_v驱动程序)"
    ;   MOV      r0,R5         ;MOV R5,32位reg
    ;   MOV      r0,R1         ;MOV r0,32位reg
    ;   MOV      r0, r1.b0;      MOV r0, r1.b0
    ;   MOV      r0, r1.w2;      MOV r0, r1.w2.
    ;   MOV      r0.b0, r1      ; MOV r0,b0, r1
    ;   MOV      r0.W1, R1      ;MOV r0.W1, R1

       MOV      R0.B3,Shared_RAM
       MOV      R0.w2,Shared_RAM
       MOV      R0,SHARed_RA
       MOV      R0.B3,标签
       MOV      R0.w2,标签
       MOV      R0,标签

       MOV      R31,标签
       MOV      R32,标签      ;****** 错误******

       MOV    R1,PRU1_CTRL+CTPPR0

       MOV      R31,ISR_JUMP64_TABLE
    ISR_JUMP64_表:
       MOV      R31,ISR_JUMP64_TABLE

       MOV      R31,NOT_VALVE_LABEL

       MOV      R31,R2
       MOV      R31.B3,R2
       MOV      R31.W1,R2
       MOV      R31.b0,R2.w2

    ;   MOV      r0.W0,0x100
    ;   MOV32   r0, Shared_RAM
    ;   MOV    r0, Shared_RAM   ; MOV r0,常量
    ;   MOV      r0,标签      ;MOV r0,符号

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我没有看到此测试用例出现任何意外错误。  此行...

    [报价用户="Brendan Graham "]   MOV      R32,标签      ;****** 错误****** [/引述]

    ...获得这些诊断程序。  

    ***** 用户消息***** - ISREG:参数无效寄存器
    ***** 用户消息***** - ISREG:参数无效注册
    "file.ASM",错误! 在第156行:[***** 用户错误***** -]目标参数无效的预定义寄存器 

    但这是预料之中的。  R32和标签都不是有效寄存器。 目标参数(R32)不是有效的寄存器。  R31是最后一个有效寄存器。

    后面的说明中有错误。  但它们都引用了CTPPR0之类的符号,这些符号可能在此文件中定义...

    [报价用户="Brendan Graham"]   。包括"PRU_hardI2C_IET_Interrupt_h.ASM"[/报价]

    我不得不对该行进行注释,因为我没有该文件。

    您最初的投诉集中在调用带有参数的宏,该参数是文件中稍后定义的标签。  在本测试案例中,我没有看到这种情况。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    George,

         感谢您的回复。

    有意     插入测试伪操作指令MOV R32标签以产生错误。 当然,我很清楚R32不是一个指令。 这是特定测试案例的全部要点。 评论;**** 错误****** 也有意放置在该位置,以提醒用户预期会出现错误。 然而,这不是我问题陈述的一部分。

    与此讨论相关的唯一测试案例是以下带有前向引用标签参数的伪操作:

       MOV      R31,ISR_JUMP64_TABLE
    ISR_JUMP64_表:

    请注意,该标签是有效的符号名称 ,因此,在引用下面的MOV宏伪操作测试代码片段时,将选择.elseif $isname(src)测试。 因此,信息“*** Source is forwarded referenced symbol name”将输出到stdio。 我声称此操作似乎有误,因为前面的测试.elseif $isdefed(src)应该返回'1',因为前向引用的标签ISR_JUMP64_table确实应该附加到符号表中, 当然,如果双通道AST解析器用于解析第一通道中的标注符号。

          否则                                     ;否则DST为INT REG    
             .mmsg "目的地注册为INT"
             如果($symcmp(is_src_reg,"1")== 0)             ;如果src是REG
                .mmsg "源是寄存器"    
                和      DST,src,src
             elseif $isdefed (src)                      ;如果src是在8k指令地址空间中定义的符号标签
                .mmsg "源是一个符号"    
                LDI      DST,src.
             elseif $isname (src)                      ;如果src可以是正向引用的符号标签
                .mmsg "***源代码是正向引用的符号名称"    
                LDI      DST,src.

    另请注意,以下使用相同伪操作,参数和标签的测试用例将生成消息"Source is a symbol",指示已采用BRANCH .elseif $isdefed(sr),此外,解析器之前已将标签ISR_JUMP64_table追加到符号表中。 这似乎表明解析器是单次解析器,并动态扩展宏,从而产生错误的结果,将正向引用的标注作为参数,如尚未追加到符号表的此类标注。 无论如何,我认为任何优秀的汇编程序都应该在展开宏之前创建符号表。

    ISR_JUMP64_表:
       MOV      R31,ISR_JUMP64_TABLE

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    要了解内置替换符号函数$isdefed如何工作,请考虑此示例。

    	数据
    
    符号1:.byte	10	;定义sym1
    
    ;测试内置函数
    	.byte	$isdefed("sym1")
    	.byte	$isdefed("SYM2")
    
    SYM2:	.byte	20	;定义SYM2
    	
    ;测试内置函数
    	.byte	$isdefed("sym1")
    	.byte	$isdefed("SYM2") 

    使用命令clpru -al file.asm组合该文件。  这将创建扩展名为.lst的商品信息文件。  以下是该列表文件中的关键字行。

    300万 0000000万 0000000万A符号1:.byte 10 ;定义符号1
    4.
    5;测试内置功能
    600000001 0000000000000001 Byte $isdefed("sym1")
    700000002 000000000000000000 Byte $isdefed ("SYM2")
    8.
    900万 000000300万 0000000万00000014 SYM20.0014万 SYM2:.byte 20 ;定义SYM2
    10.
    11;测试内置功能
    1.2万 0000.0004万 00000000000000000001 Byte $isdefed("sym1")
    1.3万 0000.0005万 00000000000000000001 Byte $isdefed ("SYM2") 

    第三列是有趣的。  它显示该汇编行的编码。  对于带有$isdefed的行,它显示了$isdefed的使用值。  您可以看到$isdefed是位置。  数值根据在装配体文件中该点符号是否有指定的值而变化。

    我意识到这不是你所期望的。  但是,美元的定义从一开始就起作用。  不仅适用于PRU汇编器,还适用于所有TI汇编器。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    后来经核实,上述讨论是由于错误地转录了用'clpru'组合的PRU代码,最初是在PASM下编写和组合的。 JMP/JAL @寄存器指令采用32位字词对齐参数,而不是字节大小的参数。 代码中显然意外删除了'>2'指令。 跳转表中的地址计算不正确导致在最终发现不恰当的转录计算错误之前进行了整整一周的验证活动。