我努力将给定的整数转换为十六进制。我没有得到正确的输出,这可能是由于位的错误移位造成的。 我尝试的算法是从第3位开始 代码:
.globl hex_str
hex_str:
movl $48, 0(%rsi)
movl $120, 1(%rsi)
movl $0, 10(%rsi)
mov $0xf, %r10d
mov $1, %r8d
mov $2, %r9d
mov $0, %ecx
loop:
inc %r8d
and %r10d, %edi
movl %edi, %r11d
shr $4, %r11d
movl %r11d, 2(%rsi)
inc %r9
cmp $9, %r8d
jg endl
jmp loop
endl:
ret
收到的输出:
1 = 0x
34 = 0x
819 = 0x
17476 = 0x
349525 = 0x
6710886 = 0x
125269879 = 0x
19088743 = 0x
2309737967 = 0x
3735928559 = 0x
3235822174 = 0x
正确的输出应包含' 0x'然后是0和正确的十六进制。
答案 0 :(得分:1)
你的程序的第二部分显然没有做你想做的事情:
and %r10d, %edi # Instruction 1
movl %edi, %r11d
shr $4, %r11d # Instruction 2
movl %r11d, 2(%rsi) # Instruction 3
说明1:
第一次执行and
指令时(在第一个循环中)rdi
掩码寄存器0xF
。在此步骤之后,仅保留寄存器的低4位。您输入的其他位是丢失。因此,即使程序的其余部分完美地工作,输出的前9位数也总是" 0x0000000" (其次是唯一的"正确的"数字)。
指示2:
因为"指令1"这种转变的结果总是为0。
但是,即使程序的其余部分完美运行(包括"指令1和#34;):如果将其移出,您认为最后一位数字如何打印?
指示3:
r11d
是一个32位寄存器。因此,以下指令将覆盖4"字符"在" 0x"之后,不仅仅是一个字符。
因为esi
的值在整个程序中永远不会改变,所以指令将始终覆盖" 0x"之后的4个字节;从不写入缓冲区的最后4位数。
换句话说:指令在每个循环中写入目标数组中的相同位置。
您希望将数字(' 0' - ' 9'以及' A' - ' F')写入数组。请注意数字' 0' - ' 9'是字节48-57,' A' - ' F'是字节65-70和'' - ' F'是字节97-102。
因此,对于2309737967,如果您希望将数字显示为" 0x89ABCDEF"则程序应写入70到9(esi)。和102如果你希望它显示为" 0x89abcdef"。
显然它并不像你想象的那么容易......