【问题标题】:x86-64 Arrays Inputting and Printingx86-64 数组输入和打印
【发布时间】:2014-11-13 03:28:35
【问题描述】:

我正在尝试将值输入到 x86-64 Intel 程序集中的数组中,但我不太明白。

我正在段 .bss 中创建一个数组。然后我尝试使用 r15 将数组的地址传递给另一个模块。在该模块中,我提示用户输入一个数字,然后将其插入到数组中。但它不起作用。

我正在尝试执行以下操作

segment .bss
dataArray resq 15                                       ; Array that will be manipulated

segment .text
mov rdi, dataArray                                      ; Store memory address of array so the next module can use it.
call inputqarray                                        ; Calling inputqarray module

在 inputqarary 里面我有:

mov r15, rdi                                            ; Move the memory address of the array into r15 for safe keeping

push qword 0                                            ; Make space on the stack for the value we are reading
mov rsi, rsp                                            ; Set the second argument to point to the new locaiton on the stack
mov rax, 0                                              ; No SSE input
mov rdi, oneFloat                                       ; "%f", 0
call scanf                                              ; Call C Standard Library scanf function
call getchar                                            ; Clean the input stream

pop qword [r15]

然后我尝试通过做输出使用输入的值

push qword 0
mov rax, 1
mov rdi, oneFloat
movsd xmm0, [dataArray]
call printf
pop rax

不幸的是,我得到的输出只有 0.00000

【问题讨论】:

    标签: arrays assembly x86-64 intel


    【解决方案1】:

    输出为 0,因为您使用了错误的格式说明符。应该是"%lf" 接下来,无需在您的程序中推送和弹出。由于您要将数据数组的地址传递给scanf,并且将在rsi中,因此只需将其传递给rsi;少一招。

    您将数组声明为 15 个 QWORDS,对吗 - 120 个字节?还是你的意思是resb 15

    这很有效,应该可以帮助您:

    extern printf, scanf, exit
    global main
    
    section .rodata
    fmtFloatIn      db  "%lf", 0
    fmtFloatOut     db  `%lf\n`, 0
    
    section .bss
    dataArray       resb 15
    
    section .text
    main:
        sub     rsp, 8                          ; stack pointer 16 byte aligned
    
        mov     rsi, dataArray
        call    inputqarray
    
        movsd   xmm0, [dataArray]
        mov     rdi, fmtFloatOut
        mov     rax, 1
        call    printf
    
        call    exit
    
    inputqarray:
        sub     rsp, 8                          ; stack pointer 16 byte aligned
    
        ; pointer to buffer is in rsi
        mov     rdi, fmtFloatIn
        mov     rax, 0
        call    scanf
    
        add     rsp, 8
        ret
    

    因为您将 rdi 中的参数传递给 C 函数,所以这不在 Windows 上。

    【讨论】:

    • 非常感谢。我真的不知道你做了什么与我不同,但它现在有效。不知道就不舒服。我已将格式从“%f”修复为“%lf”。这并没有立即解决。我删除了我的代码,然后慢慢地建立在你那里的东西上,它对我来说看起来是一样的。还要感谢有关将其直接加载到数组中的提示。是的,我确实打算分配那么多内存。我正在直接在程序集中构建一个数组。
    • %fdouble 的说明符,用于printf,但不是scanf。你不能printffloat,因为在将args 传递给可变参数函数时应用了C 提升规则,所以float args 作为double 传递。在%f 转换中忽略l 修饰符是printf 的方便扩展,但它是非标准的。 (long double uses %Lf). (%f` 对于 scanf 确实意味着 float*,而 %lfdouble*)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多