【问题标题】:NASM Linux 32-bit: scanf, printf callsNASM Linux 32 位:scanf、printf 调用
【发布时间】:2015-06-29 03:01:26
【问题描述】:

我编写了简单的汇编代码,它使用printfscanf 分别在命令行中写入和读取数字。对于这个特定的代码,我得到的输出与给定的输入不同。似乎打印的第一个值是 [var1]+[var2]*2^8 。但是,通过将变量 var1var2 的大小增加到 4 个字节,代码会给出正确的输出。怎么样?

    ;assemble and compile with :
    ;nasm -f elf testing.asm && gcc -m32 -o testing testing.o
    extern printf,scanf

    ;store eax,ebc,ecx,edx onto the stack
    %macro push_reg 0
    push edx
    push ecx
    push ebx
    push eax
    %endmacro

    ;restore eax,ebx,ecx,edx
    %macro pop_reg 0
    pop eax
    pop ebx
    pop ecx
    pop edx
    %endmacro

    section .text
    global main
    main:
    ;reads number var1
    push_reg          
    push var1
    push formatin
    call scanf          ;scanf("%d",var1);
    add esp,8           ;restoring stack pointer 
    pop_reg            

    ;reads number var1
    push_reg
    push var2
    push formatin
    call scanf        ;scanf("%d",var2);
    add esp,8         ;restoring stack pointer 
    pop_reg           

    ;printing number var1
    push_reg          
    push dword[var1]
    push formatout
    call printf       ;printf("%d",content of var1);
    add esp,8         ;restoring stack pointer 
    pop_reg          

    ;printing number var2
    push_reg
    push dword[var2]
    push formatout
    call printf       ;printf("%d",content of var2);
    add esp,8         ;restoring stack pointer 
    pop_reg       

    exit:
    mov eax,1
    int 0x80

    section .bss
    var1 resb 1
    var2 resb 1

    section .data
    formatout: db "%d",10,0
    formatin: db "%d",0

输入:

1
1

输出:

257
1

【问题讨论】:

    标签: linux assembly printf nasm scanf


    【解决方案1】:

    您告诉 scanfprintf 您正在扫描/打印整数,这些整数通常是 32 位(或 4 字节)值。所以他们表现得好像他们是,在你提供的地址使用那么多数据。

    【讨论】:

    • 在将 var1var2 的内容作为 printf 的参数推送到堆栈时,它们作为 dword 传递。因此,它们每个都是 32 位数字。对吗?
    • @user148865 我很确定您将它们声明为每个仅一个字节。您应该更改您的声明,使其每个为 4 个字节。
    • @1.618:是的,我在问题中提到,通过将每个变量设置为每个 4 字节,它可以正常工作。为什么当它们为 1 字节时它不起作用?我将每个参数作为 dword 传递。所以,4字节字。对吗?
    • @user148865 想想如果你这样做会在 c 中发生什么:char a = 10; printf("%d", *(int*)&a);
    • 是的,您将它们作为 DWORD 传递给函数。您传递了我们 DWORD 大小的变量的地址。你传递的地址指向的内存只有1个字节。
    猜你喜欢
    • 2013-12-03
    • 1970-01-01
    • 2017-03-20
    • 2015-06-25
    • 2015-06-09
    • 1970-01-01
    • 2013-05-14
    • 2014-12-27
    • 2013-05-31
    相关资源
    最近更新 更多