如何使用tcl将十六进制地址拆分为多个字段

如何使用tcl将十六进制地址拆分为多个字段,tcl,Tcl,我试图使用tcl将32位十六进制地址拆分为多个字段,然后显示每个字段,然后将几个字段分配给另一个变量。我在下面试过,但没有成功。在这方面你能帮我吗 //pseudo code that I want to achieve field1 = addr_in[31:30] field2 = addr_in[29:14] field3 = addr_in[13:11] ##field 3 value field4 = addr_in[10:1] field5 = addr_in[0]

我试图使用tcl将32位十六进制地址拆分为多个字段,然后显示每个字段,然后将几个字段分配给另一个变量。我在下面试过,但没有成功。在这方面你能帮我吗

//pseudo code that I want to achieve  
field1 = addr_in[31:30]  
field2 = addr_in[29:14]  
field3 = addr_in[13:11]  ##field 3 value
field4 = addr_in[10:1]  
field5 = addr_in[0]

addr_out = {field3, field2, field4}  
print field1,field2,...field5 and addr_out
...
我尝试了列表lassign,但后来意识到字符串范围是最好使用的

    ## actual code below
    #! /usr/bin/tclsh

    set addr  "abcd1234"  ## assigning a value to addr
    puts $addr

    set field1 [string range $addr 0 1]  ## this sets field1 as ab. 

    set field2 [string range $addr 18 20]  ## doesn't print anything
    puts $field2

    set field3 [string range $addr 2 17]
    puts $field3

    set field4 [string range $addr 21  end-1]
    puts $field4

    set field5 [string index $addr end]
    puts $field5

    set addr_out [concat $field3 $field2 $field4]
    puts $addr_out

    exit 0
    ### end of the code
然而,field1变量将只打印“ab”,而不是 [31:30]位中的addr_和field2、field3无法显示,因为它们的范围超出了界限,所以我尝试使用二进制格式H*$field1将$addr转换为二进制,然后将其从高到低,然后获取每个字段值,但无法获取

在以下方面也进行了尝试:

   set field1 [string range $addr 0 1]  
   puts $field1 [binary format H* $addr field1]  

谢谢你的帮助

要提取位,首先要将十六进制数转换为位字符串;我们可以使用
scan
format
来实现这一点。(助记符:
%x
用于处理十六进制值,
%b
用于处理二进制值。)

然后我们可以使用
string range
(请记住,此时实际上得到了一个大端值):

如果要将其转换为十进制,请再次扫描:

set field1value [scan $field1 "%b"]
我们还可以一次提取多个字段,边提取边转换为十进制:

scan $bits "%1b%10b%3b%16b%2b" field5 field4 field3 field2 field1
(使用
s
而不是
b
获取位字符串片段本身。)


如果您使用的是较旧版本的Tcl,则可能需要使用
二进制格式
二进制扫描
。我发现它们比普通的
格式
扫描
更难使用,但您可能不同意。例如,要将地址转换为位字符串

binary scan [binary format "H*" $addr] "Bu*" bits

多纳尔,谢谢你的建议。我将尝试一下。在我的编辑中切换到
%032b
是由Schelte Bron在带外建议的。非常感谢!
scan $bits "%1b%10b%3b%16b%2b" field5 field4 field3 field2 field1
binary scan [binary format "H*" $addr] "Bu*" bits