GAS汇编程序打印浮点



我正在读一本关于如何使用NASM在汇编中编程的书,但在构建一个打印3.1400000的程序时遇到了问题。

代码可能有一些问题,比如在中使用错误的语句section .data pi: .float 3.14应该是双quad类型,但我不知道是哪种伪操作地图;我试过了。但是dq不是那样的。

此外,我读到调用堆栈需要在程序启动前对齐,我希望使用基指针可以解决这个问题,否则程序将打印段错误。

另一个需要注意的是,我使用GAS和Intel语法,因此我不确定下面的语法映射是否正确。

代码:

#fmtflt.s
.intel_syntax noprefix
.extern printf 
.section .data
pi: .float 3.14
.section .rodata
fmtflt: .ascii  "%1f12"
.section .text
.globl main
main:
push    rbp
mov     rbp, rsp
mov     rax, 0             # set total numers xmm register  
movq    xmm0, [pi]          # set content pi to
mov     rdi, offset fmtflt  # set address format string
call    printf              # call printf function
mov     rsp, rbp
pop     rbp
ret

编译:gcc-无饼图-o fmtflt fmtflt.s

输出:

实际:0.00000
预期:3.140000

有人能填补缺失的部分,让程序打印出预期的输出吗?

在节中使用了错误的语句。data pi:.foat 3.14的类型应该是双quad,但我不知道哪个伪操作映射到它;

使用.double汇编一个8字节的双精度浮点值。看见https://sourceware.org/binutils/docs/as/i386_002dFloat.html#i386_002dFloat.

然后,正如Joseph所指出的,看看这条线:

mov     rax, 0             # set total numers xmm register  

正如注释所说,rax应该设置为用于传递参数的xmm(SSE(寄存器的总数。请参阅x86-64 SysV ABI的图3.4,它是在使用它的Linux等系统上调用约定的权威参考。您将在xmm寄存器中传递1个参数(在下一行(,因此将rax设置为1,而不是0。指令mov eax, 1具有相同的效果(因为移动到32位寄存器中会使64位寄存器的上半部分为零(,并且少一个字节。

有了这些更改,程序为我正确地打印了3.140000

我也读到调用堆栈需要在程序启动前对齐,我希望使用基指针可以解决这个问题,否则程序将打印段错误。

是的,你把那部分说对了。

相关内容

  • 没有找到相关文章

最新更新