Assembly 在asm中打印浮点
在C的帮助下,我有以下程序在asm中打印浮点:Assembly 在asm中打印浮点,assembly,x86,x86-64,Assembly,X86,X86 64,在C的帮助下,我有以下程序在asm中打印浮点: .section .rodata format: .ascii "Your number is: %f\n\0" .section .text .globl main main: lea format(%rip), %rdi mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7 mov $0, %eax add $-8, %r
.section .rodata
format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
lea format(%rip), %rdi
mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7
mov $0, %eax
add $-8, %rsp
call printf@plt
add $8, %rsp
mov $0, %eax
ret
>>> p $xmm0
$2 = {
v4_float = {[0] = 2.70000005, [1] = 0, [2] = 0, [3] = 0},
v2_double = {[0] = 5.3194953090036137e-315, [1] = 0},
...
}
但是,我在将其与以下组件组装时出错:
int_c.s:7:错误:不支持的指令'mov'
您是否不允许在xmm
寄存器中添加即时数据,或者上述程序出现了什么问题
更新:我编译了它,但我认为我的问题是
movq
接受8字节,但我希望在fp寄存器中得到一个4字节的浮点:
mov $2.7, %eax # using '2.7' to be more readable
movq %eax, %xmm0
在单步执行说明之后,在调用printf
之前,它看起来是正确的:
.section .rodata
format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
lea format(%rip), %rdi
mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7
mov $0, %eax
add $-8, %rsp
call printf@plt
add $8, %rsp
mov $0, %eax
ret
>>> p $xmm0
$2 = {
v4_float = {[0] = 2.70000005, [1] = 0, [2] = 0, [3] = 0},
v2_double = {[0] = 5.3194953090036137e-315, [1] = 0},
...
}
以下是程序的工作示例,将值写入内存,然后使用将浮点转换为双精度浮点:
format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
push %rbp
mov %rsp, %rbp
lea format(%rip), %rdi
# move float to memory and upgrade to 8 bytes
movl $0b1000000001011001100110011001101, -4(%rbp)
cvtss2sd -4(%rbp), %xmm0
mov $1, %eax
call printf@plt
mov $0, %eax
mov %rbp, %rsp
pop %rbp
ret
rax
将是printf
中的浮点参数数。请参阅:。事实上,这就是问题所在。当有疑问时,请参考指令集参考。@Jester当然,movq
可以工作,但在添加时似乎仍然存在问题,因为数字显示0
@Jester更新了问题。printf
需要双精度所以它要查看gdb的低64位(v2\u double
)这不是您想要的值。无论如何,将浮点常量输入寄存器的最典型方法是从内存加载。通常您希望在.section.rodata
中使用格式。文件顶部的默认部分是.text
,因此您可以将其放在此处。另外,0-终止的正常方式是使用.asciiz
,而不是使用显式\0
的.ascii
。此外,cvtss2sd
也可以与寄存器一起工作,因此您不必遍历内存。除此之外,这对于未优化的代码也很好。不需要将RBP设置为帧指针,您可以pushq$0b100000000101100111001101
对齐堆栈并存储浮点常量。(仍然只是读取它的低4字节,忽略符号扩展的高半部分。)@Jester我如何使用寄存器执行上述操作?我尝试从rax
移动到xmm0
,但当我尝试时,这给了我0
;movd%eax,%xmm0;cvtss2sd%xmm0,%xmm0