3

この 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 を使用しており、Kip Irvine のアセンブリ言語 x86 プロセッサの第 6 版ブックを使用しています。

回答者の回答の1つからMASMに書き込もうとしたコードを更新します。エラーが発生し続けます。前に言ったように、私は Kip Irvine のアセンブリ言語を使用しているので、ライブラリ リンクを含める必要があります INCLUDE Irvine32.inc

これはエラー>>>> programb.obj です: エラー LNK2019: 未解決の外部シンボル _scanf が関数 _main@0 で参照されています

含む Irvine32.inc

誰かがこれを正しくするのを手伝ってくれますか

.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 _main@0

アセンブリ言語のコードで申し訳ありません....読みやすいようにフォーマットする方法がわかりません....

4

4 に答える 4

9

フラグを gcc に使用-Sして、アセンブリ コードを生成 できます。gcc myfile.c -S -o myfile.s

私が言いたいのは、このアセンブリ ファイルがすべての質問に答えるはずだということです。

于 2010-11-05T08:09:29.120 に答える
5

私は退屈だったので、あなたのためにこれをしました。MASM ではなく NASM を使用しました。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
于 2010-11-05T08:34:24.757 に答える
1

幸いなことに、printf関数は、アセンブリからであっても、ほとんどすべてを実行します。おそらく、スタックについて、およびスタックにプッシュされた引数を取る関数を呼び出す方法について読んだことがあるでしょう。についても同様ですprintf。スタックの一番上がフォーマット文字列への参照になるように、引数を逆の順序でプッシュします。次に、あなたがしなければならないことは次のとおりです。

       call     printf

私の記憶が正しければprintf、少なくとも 1 つの引数があり、その最初の引数 (書式文字列) がスタック ポインターが指している引数であることを知っています。そのprintfため、フォーマット文字列をスキャンして、i や i+1 などの他の引数を置き換える必要があるかどうかを確認します。繰り返しprintfますが、 はこれを行っています。心配する必要はありません。

お役に立てれば!

PS Re: 以前の回答です。通常、アセンブリを学習しようとしている場合、コンパイラによって生成されたアセンブリ コードを見ることは役に立ちません。最適化が有効になっていない場合でも、出力は人間が読むためのものではありません。

于 2010-11-05T08:29:46.700 に答える
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
于 2012-11-05T22:46:14.987 に答える