2010-11-05 52 views
3

我需要這個C代碼翻譯成彙編語言代碼轉換C代碼到大會

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int answer, i; 
    int right, wrong; 
    right = 0; 
    wrong = 0; 

    for(i =1; i < 11; i = i+1){ 
     printf("What is %d + %d? ", i,i); 
     scanf("%d", &answer); 

     if(answer == i + 1) { 
      printf("right! "); 
      right++; 
     } 
     else { 
      printf("Sorry, you're wrong. "); 
      printf("The answer is %d. ", i + 1); 
      wrong++; 
     } 
    } 
    printf("You got %d right and %d wrong. ", right, wrong); 
    return 0; 
} 

我真的只需要知道如何將一個變量與字符串彙編語言如上面的C代碼相結合。我想我可以處理所有其他事情。有人能告訴我嗎?我會不得不使用某種參考[]。

注意我使用MASM和工作了硤歐文的彙編語言的x86處理器第6版書

更新繼承人我試圖將代碼從回答者的答案我的一個寫到MASM不斷收到錯誤。就像我說我使用硤歐文的彙編語言,所以我必須包括庫鏈接之前,先添加Irvine32.inc

這是錯誤>>>> programb.obj:錯誤LNK2019:無法解析外部符號_scanf在函數_main引用@ 0

INCLUDE Irvine32.inc

能有人幫助我GE牛逼這一權利

.data 
string1 db "What is %d + %d? ", 0 
string2 db "%d", 0 
string3 db "right! ", 0 
string4 db "Sorry, you're wrong. The answer is %d", 10, 0 
string5 db "You got %d right and %d wrong.", 10, 0 


answer dd 0 
right dd 0 
wrong dd 0 

.code 
main PROC 

    mov ebx, 1 

L1: 

    cmp ebx, 11 
    je L2 

    push 1 
    push ebx 
    mov edx,OFFSET string1 
    call WriteString 
    add esp, 12 

    push answer 
    mov edx,OFFSET string2 
    call scanf 
    add esp, 8 

    inc ebx 
    cmp answer, ebx 
    jne L3 

    push ebx 
    mov edx,OFFSET string3 
    call WriteString 
    add esp, 8 
    inc right 

    jmp L1 

L3: 

    push ebx 
    mov edx,OFFSET string4 
    call WriteString 
    add esp, 8 
    inc wrong 

    jmp L1 

L2: 

    push wrong 
    push right 
    mov EDX,OFFSET string5 
    call WriteString 
    add esp, 12 


    exit 

main ENDP 
END main 

programb.obj : error LNK2019: unresolved external symbol _scanf referenced in function [email protected] 

我對彙編語言代碼對不起....我不知道怎樣格式化它,所以它可以更容易閱讀....

+0

所以你問如何從裝配調用printf,或正在問如何做整數字符串轉換,然後在彙編中的字符串連接?這是兩件完全不同的事情。 – 2010-11-05 12:33:53

+0

基本上字符串連接 – jwill22 2010-11-05 20:28:58

回答

9

您可以使用-S標誌gcc生成彙編代碼: gcc myfile.c -S -o myfile.s

我的意思是這個程序集文件應該回答你所有的問題。

+2

...並附加標誌'-masm = intel'來獲得一個MASM外觀代碼(intel語法):'gcc -S -masm = intel myfile.c -o myfile.s' – Noe 2010-11-05 08:18:02

+0

不幸的是這將生成委託給libc的代碼,而不是生成代碼來實際執行操作。 – 2010-11-05 08:24:02

+3

然後他可以在靜態模式下編譯,但重新編碼'printf()'將會是一個地獄! – 2010-11-05 08:27:33

1

幸運的是,printf函數即使在組裝時也會爲您做幾乎所有的事情。你可能已經閱讀過關於堆棧的內容,以及如何調用帶有堆棧參數的函數。 printf也是如此。按相反順序推入參數,以便堆棧中的頂層事物是對格式字符串的引用。然後,所有你需要做的是:

 call  printf 

如果我沒有記錯,printf知道它至少有一個說法,那第一個參數(格式字符串)是堆棧指針所指向的一個。那麼printf將掃描格式字符串,並檢查是否需要替換其他任何參數,如i和i + 1。再次,printf這樣做,你不需要擔心它。

希望這有助於!

P.S. Re:以前的答案,如果你正在學習彙編,通常查看編譯器生成的彙編代碼是沒有用的。即使沒有啓用優化,輸出也不適合人類閱讀。

+2

好吧,顯然它並不適用於人類,但是您可以輕鬆編寫一個簡單的函數,在非常簡單的情況下調用printf()來查看它的調用方式。 – 2010-11-05 08:31:17

+0

你能告訴我一個例子嗎? – jwill22 2010-11-05 08:36:08

5

我很無聊,所以我爲你做了這個。我用NASM,而不是MASM。我假定EBX是一個被保存的被保存的寄存器。代碼不是特別好。:-)

section .data 
answer: dd 0 
right: dd 0 
wrong: dd 0 

section .text 
extern printf 
extern scanf 
global main 
main: 

    push ebx 
    mov ebx, 1 

.loop_start: 

    cmp ebx, 11 
    je .loop_end 

    push 1 
    push ebx 
    push .string0 
    call printf 
    add esp, 12 

    push answer 
    push .string1 
    call scanf 
    add esp, 8 

    inc ebx 
    cmp dword [answer], ebx 
    jne .wrong 

    push ebx 
    push .string2 
    call printf 
    add esp, 8 
    inc dword [right] 

    jmp .loop_start 

.wrong: 

    push ebx 
    push .string3 
    call printf 
    add esp, 8 
    inc dword [wrong] 

    jmp .loop_start 

.loop_end: 

    push dword [wrong] 
    push dword [right] 
    push .string4 
    call printf 
    add esp, 12 

    pop ebx 
    xor eax, eax 
    ret 

section .data 

.string0: 
    db "What is %d + %d? ", 0 
.string1: 
    db "%d", 0 
.string2: 
    db "right! ", 0 
.string3: 
    db "Sorry, you're wrong. The answer is %d", 10, 0 
.string4: 
    db "You got %d right and %d wrong.", 10, 0 
+0

你可以Pleeeeeez *雙手合十*把它放在MASM ...... Pleez – jwill22 2010-11-05 20:37:01

+0

@ user498084我沒有真正使用過MASM,但它應該是非常相似的。我相信你可以弄明白。另外,對於@Rob的憤怒評論不被要求。 – asveikau 2010-11-06 18:39:51

+0

好吧,我覺得你....我試過射擊(悲傷的臉)我得到它運行,但它沒有運行像C代碼。都很好。忘記他是應得的。如果他沒有任何建設性的話語或貢獻,那麼他應該關閉地獄 – jwill22 2010-11-07 17:38:01

0

舉個例子,這條線在C編程語言:

printf("\n%d%s%d\n\n",num1," is not equal to ",num2); 

等同於:

printf PROTO arg1:Ptr Byte, printlist:VARARG 
.data 
msg1fmt byte 0Ah,"%d%s%d",0Ah,0Ah,0 
msg1 byte " is not equal to ",0 
num1 sdword 5 
num2 sdword 7 
.code 
main proc 
INVOKE printf, ADDR msg1fmt, num1, ADDR msg1, num2 
ret