2013-10-07 36 views
0

[解决] 我试图做我自己的汇编代码做什么类似的C代码就可以了:创建变量(Linux)的

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

嗯,这是在C,所以我m在linux下使用extern函数与NASM一起工作。 scanf和printf,首先用nasm然后用gcc编译。 这里是我的代码(是不对的: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 :(

编译器错误:

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

另一件事:我需要对准这个情况下,栈,顺便说一下?

谢谢你们! :)

EDIT解决了整个程序!至少,至少,我可以用printf打印这个变量。 scanf函数后面我会做什么,然后我会在这里分享最后的结果:

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 :) 

回答

1

要地址EBP-4装入EAX,使用lea eax, [ebp-4]。 (这与推送地址不一样)。

为了推内存位置的值EBP-4,push dword [ebp-4]应该工作。

然后,您还需要指定mov之一的操作数大小: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 
+0

感谢US2012再次:)现在我知道如何解决在内存的位置,NASM加载到寄存器和推进价值。谢谢。现在取决于我:) – int3

+0

@ int3我已经添加了一个非常接近您的解决方案的工作尝试。希望这可以帮助! – us2012