0

[SOLVED] I'm trying to do my own assembly code to do what similar C code will do:

main()
{
scanf("%d",&integer_var); // here must be the address of the integer_var
printf("Your Value is:%d",integer_var);
}

Well this is in C, so I'm doing with NASM under linux with extern functions. scanf and printf and compile first with nasm and then with gcc. Here's my code (is not right :D)

SECTION .text

argstr: db "%d",10,0
str: db "Your value is:%d",10,0

extern printf
extern scanf

SECTION .data

global main

main:
        push ebp
    mov esp,ebp
    sub esp, 0x10 ;ok integer right?
    mov [ebp-0x4],0x0 ;just put 0 number on our integer variable
    mov eax,(ebp-0x4) ;here i don't know how to push the address of ebp-0x4
    push ecx ;first push is last argument so here's our address to scanf
    push argstr ;just the string format
    call scanf ;call that to input something
    ;I have no idea how to do this
    ;but if i don't do this i get an error
    ;because the scanf won't clear the arguments on stack
    ;and what scanf can't return
    pop edx ;maybe help here? but it works fine
    pop edx
    push [-0x4(ebp)] ;i want the value of our var :D
    push str
    call printf
    pop edx ;clear the stack to avoid "segment fault" or something similar
    pop edx
    mov esp,ebp
    pop ebp
    ret ;the end :(

Compiler error:

a.asm:18: error: invalid operand type
a.asm:28: error: parser: expecting ]

Another thing: Do I need to align the stack on this case, by the way?

thanks guys ! :)

EDIT solved whole program! well at least, I can print the variable with printf. scanf i will do later and then I will share here the last result:

SECTION .text
str: db "Value is:%d",10,0
extern printf
SECTION .data
global main
main:
        push ebp                ;the main function starts here.
        mov ebp,esp
        ;
        sub esp,4               ;we need 4bytes of space for the integer
        and esp,0xfffffff0      ;align the stack 
        mov [esp-4], dword 0xff ;move the value 0xff to our var
        mov eax,[esp-4]         ;move our variable value to the eax
        push eax                ;second argument of printf
        push str                ;first argument of printf
        call printf             ;printf
        ;
        add esp,16              ;this add to the stack pointer what we pushed basicly
        mov ebp,esp             ;if we don't do add 16 to esp it shows us
        pop ebp                 ;a segment fault cuz ret doesnt pop saved ebp
        ret                     ;of who whatever called this program :)
4

1 回答 1

1

要将地址加载EBP-4EAX中,请使用lea eax, [ebp-4]。(这与推送地址不同。)

为了将值推送到内存位置EBP-4push dword [ebp-4]应该可以工作。

然后,您还需要为其中一个movs 指定操作数大小:mov [ebp-4], dword 0x0.

这些将修复您当前的汇编程序错误,并使您的程序编译,但其中还有一些其他错误可能会阻止它运行。

这是一个与您接近的工作尝试:

;note the sections, the string literals are better in .rodata
;all code goes in .text

SECTION .rodata 
;no newline after scanf string
argstr: db "%d",0 
str: db "Your value is: %d",10,0

SECTION .text 
extern printf 
extern scanf 
global main

main:
    push ebp
    mov ebp,esp ;move esp to ebp, NOT other way round!
    sub esp, 4  ;4 bytes are enough for the local variable
                ;there are NO alignment requirements for this program

    lea eax,[ebp-4]
    push eax
    push dword argstr

    call scanf

    add esp, 8  ;since we don't actually need the popped values
                ;we can increment esp instead of two pop edx

    push dword [ebp-4]
    push dword str

    call printf

    add esp, 8

    mov esp,ebp
    pop ebp
    ret
于 2013-10-07T22:36:40.533 回答