在Go中使用strconv处理负十六进制值

huangapple go评论72阅读模式
英文:

Using strconv for negative hex values in Go

问题

我过去一天左右一直在使用Go构建一个汇编器,没有什么好的理由,只是为了熟悉这种语言。这是我第一个真正使用Go编写的程序,所以我预料到会遇到问题,但是我一次又一次地遇到了一个一致的错误。我刚刚找到了其他解决方法来修复其他情况下的错误,但是这一次我认为我需要一个答案,这样我才觉得我在做对的事情。

基本上,我需要解析大量的字节值。其中一些是有符号字节,所以-1 = 0xFF等等。当计算标签的地址时,我需要找到它与当前地址的偏移量。以下代码是我用来获取偏移量的简化基本版本:

// lbladdr保存目标标签地址
// address保存内存中的当前地址
// label[x]保存偏移量
if address > lbladdr {
    lbladdr -= address
}
label[x] = strconv.FormatInt(int64(lbladdr), 16)

这对于正值有效,但是当我得到一个负地址(address > lbladdr)时,我得到的不是像FE这样的值,而是-2。我不明白为什么标准库会在一个十六进制数后面添加一个负号,我也没有在文档中找到任何相关信息。我在很多其他地方都找过,但是似乎没有人遇到同样的问题。

我希望这只是我这边的一些小问题,可以简单修复。

英文:

I've been building an assembler for no good reason the past day or so using Go so I can get familiar with the language. It's my first real program using Go so I expected problems, but I have a consistent bug coming up time and time again. I just figured out other hacky ways to fix it in other cases, but this time I think I need an answer so I feel like I'm actually doing this right.

Basically, I have to parse tons of byte values. Some of these are signed bytes so -1 = 0xFF and so on. When calculating the address of a label I need to find the offset of it from the current address. The following code is a stripped down basic version of what I use to get the offset:

//	lbladdr holds the target label address
//	address holds current address in memory
//	label[x] holds the offset
if address > lbladdr {
	lbladdr -= address
}
label[x] = strconv.FormatInt(int64(lbladdr), 16)

This works for positive values, but when I get a negative address (address > lbladdr) then instead of getting a value like FE I get -2. I don't get why the standard library would append a negative sign to a hex number and I haven't been able to find anything in the documentation about it. I've looked a lot of other places but I can't seem to find anyone with the same problem either.

I hope it's just something on my end that is a simple fix.

答案1

得分: 3

在十六进制数上使用负号是完全合理的。我知道在使用汇编语言时,通常使用实际的位模式来表示十六进制寄存器的符号。然而,Go语言并不知道你这样做。Go的格式化函数也没有编写支持以CPU寄存器中的十六进制值的方式来表示的功能。此外,位模式将取决于你要存储它们的寄存器大小(16位、32位、64位以及大端和小端)。所以仅仅使用基数是不足以按照你想要的方式打印它们的。你需要编写自己的格式化库,以支持你想要表示的寄存器类型的格式化。

英文:

It's perfectly reasonable to use a negative sign on hexadecimal numbers. I know that when working with assembly it's common to use the actual bitpattern for the register you are representing in hex to represent the signs. However Go doesn't know you are doing that. Neither is go's formatting function written to support hex values as they would be in a CPU register. Further the bitpatterns will differ depending on the register size (16 vs 32 vs 64 and big vs little endian). you would be storing them in. So the base isn't enough to print them the way you want. You will need to write your own formatting lib that supports formatting for the type of Register you want to represent.

答案2

得分: 2

这是设计如此:http://golang.org/src/pkg/strconv/itoa.go?s=628:668#L8

你可能想要将其转换为uint64类型:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i := -1
    fmt.Printf("%x\n", uint64(i))
    fmt.Println(strconv.FormatUint(uint64(i), 16))
}
英文:

It's by design: http://golang.org/src/pkg/strconv/itoa.go?s=628:668#L8

What you may want is to cast to uint64:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i := -1
    fmt.Printf("%x\n", uint64(i))
    fmt.Println(strconv.FormatUint(uint64(i), 16))
}

huangapple
  • 本文由 发表于 2013年3月18日 10:46:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/15469015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定