2013-10-07 60 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