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

时间:2017-05-31 22:55:52

标签: 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]

addr_out = {field3, field2, field4}  
print field1,field2,...field5 and addr_out
...

我尝试过list 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"代替 addr_in [31:30]位以及field2,field3无法显示,因为它们的范围超出范围,所以我尝试使用二进制格式H * $ field1将$ addr转换为二进制,然后将其从高位变为低位然后得到每个字段值,但无法得到它。

也在下面尝试过:

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

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

要提取位,我们首先要将十六进制数转换为位串;我们可以使用scanformat执行此操作。 (助记符:%x用于处理 x 值,%b用于处理 b inary值。)

set bits [format "%032b" [scan $addr "%x"]]

然后我们可以使用string range(请记住,此时你已经有效地获得了一个大端值):

set field1 [string range $bits 30 31]

如果您想将其转换为小数,再次scan

set field1value [scan $field1 "%b"]

我们也可以一次提取多个字段,然后转换为十进制:

scan $bits "%1b%10b%3b%16b%2b" field5 field4 field3 field2 field1

(使用s代替b自行获取位字符串。)

如果您使用的是旧版Tcl,则可能需要使用binary formatbinary scan。我发现它们比普通formatscan更难使用,但您可能不同意。例如,要将地址转换为位串...

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