繁体   English   中英

将C代码翻译为Assembly

[英]Translate C code to Assembly

我需要将此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版

更新继承我试图从回答者的答案之一写入MASM的代码我一直收到错误。 就像我在使用Kip Irvine的汇编语言之前所说的那样我必须包含库链接INCLUDE Irvine32.inc

这是错误>>>> programb.obj:错误LNK2019:函数_main @ 0中引用的未解析的外部符号_scanf

包括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

我很抱歉汇编语言代码....我不知道如何格式化它所以它更容易阅读....

您可以使用-S标志来生成汇编代码: gcc myfile.c -S -o myfile.s

我的意思是这个汇编文件应该回答你的所有问题。

我很无聊,所以我为你做了这个。 我使用的是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

幸运的是, printf功能几乎可以为您完成所有操作,即使是从装配中也是如此。 您可能已经阅读过堆栈,以及如何调用带有已经在堆栈上推送的参数的函数。 printf也是如此。 以相反的顺序推送参数,以便堆栈顶部的东西是对格式字符串的引用。 那么你所要做的就是:

       call     printf

如果我没记错的话, printf知道它至少有一个参数,并且第一个参数(格式字符串)是堆栈指针指向的参数。 因此, printf将扫描格式字符串并检查是否需要替换任何其他参数,例如i和i + 1。 再次, printf这样做,你不必担心它。

希望这可以帮助!

PS Re:以前的答案,如果您正在尝试学习汇编,通常查看编译器生成的汇编代码没有帮助。 即使没有启用优化,输出也不适合人类阅读。

作为一个例子,这一行用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM