Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly Can';在汇编x86中计算printf函数并使用操作数_Assembly_X86_Printf_Nasm_Exponentiation - Fatal编程技术网

Assembly Can';在汇编x86中计算printf函数并使用操作数

Assembly Can';在汇编x86中计算printf函数并使用操作数,assembly,x86,printf,nasm,exponentiation,Assembly,X86,Printf,Nasm,Exponentiation,我已经对发布这个问题感到紧张了,但问题来了。我正在尝试设计一个汇编程序,以接受两个整数,然后接受一个操作数(*、+、或^)。然后,根据操作数,程序将根据选择的操作数执行算术序列。输出必须完全像这样,假设用户输入5,然后用户输入6,最后用户输入a*,程序必须打印出来 OP 5 * 6 = 30 现在,由于某种原因,我无法理解printf的概念,所以我在底部的printfunction是我尝试打印出来的荒谬方式。如果有人能向我解释printf是如何工作的,我很想听!我有非常基本的堆栈知识。另外,我

我已经对发布这个问题感到紧张了,但问题来了。我正在尝试设计一个汇编程序,以接受两个整数,然后接受一个操作数(*、+、或^)。然后,根据操作数,程序将根据选择的操作数执行算术序列。输出必须完全像这样,假设用户输入5,然后用户输入6,最后用户输入a*,程序必须打印出来

OP 5 * 6 = 30
现在,由于某种原因,我无法理解printf的概念,所以我在底部的printfunction是我尝试打印出来的荒谬方式。如果有人能向我解释printf是如何工作的,我很想听!我有非常基本的堆栈知识。另外,我在这里没有指数函数,因为我不知道如何用汇编语言实现它。最后,我有一个与程序无关的问题要问那些真正的计算机之神……我绝对讨厌汇编语言,我很难用这种语言编写基本的操作。我喜欢在C、CPP和Java中工作……这门语言对于程序员的日常生活来说是绝对必要的吗?或者这是一门关于人们在没有打火机之前是如何生火的历史课?不管怎样,欢迎回答任何问题,并提前感谢您

;program to add, multiply, or give the power of a number

%include "asm_io.inc"


segment .data 


prompt1 db    "Enter a number: ", 0        ;prompts
prompt2 db    "Enter another number: ", 0
prompt3 db    "Enter an operand", 0
prompt4 db    "OP ", 0    ;idiotic prompts for printing
prompt5 db    " = ", 0    ;another printing prompt

segment .bss

num1  resd 1    ;variable for 1st number
num2  resd 1    ;variable for 2nd number
op    resd 1    ;variable for operand


segment .text

    global  asm_main
asm_main:
    enter   0,0               ; setup routine
    pusha

    restart:
        mov     eax, prompt1      ; print out prompt
        call    print_string
        call    print_nl

        call    read_int          ; read integer
        mov     [num1], eax       ; store into num1
        call    print_nl

        mov     eax, prompt2      ; print out prompt
        call    print_string
        call    print_nl

        call    read_int          ; read integer
        mov     [num2], eax     ; store into num2
        call    print_nl

        mov     eax, promtp3    ;print out prompt
        call    print_string
        call    print_nl

        call    read_char       ;read operand and dispose of null
        call    read_char
        mov     [op], eax       ;store operand in [op]
        call    print_nl

        cmp     [op], '*'       ;operand comparison
        jne     jmp1
        call    mulFun
        jmp     restart

jmp1:   cmp     [op], '+'       ;operand comparison
        jne     jmp2
        call    sumFun
        jmp     restart

jmp2:   cmp     [op], '^'       ;operand comparison
        jne     jmp3
        call    expFun
        jmp     restart

jmp3:   cmp     [op], 'e'       ;exit function
        je      end1

end1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    call    print_nl          ; pr
    popa
    mov     eax, 0            ; return back to C
    leave
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mulfun:                     ;multiplication function
    mov     ebx, [num1]
    mov     ecx, [num2]
    imul    ebx, ecx
    jmp     printFun

sumFun:                     ;sum function
    mov     ebx, [num1]
    mov     ecx, [num2]
    add     ebx, ecx
    call    printFun


printFun:                   ;printing function
    mov     eax, [prompt4]
    call    print_string
    mov     eax, [num1]
    call    print_string
    mov     eax, [op]
    call    print_string
    mov     eax, [num2]
    call    print_string
    mov     eax, [prompt5]
    call    print_string
    mov     eax, ebx
    call    print_string
    call    print_nl
    ret

无论我在哪里发现一个问题,我都在评论中添加了***。需要注意的几点:

  • 你的一些标签上有打字错误
  • NASM区分大小写,因此mulfun与mulfun不同
  • 如果一条指令包含一个或多个不涉及寄存器(src或目标)但引用内存的操作数,则需要指定内存操作数的大小。例如
    cmp[op],“+”
    必须指定[op]引用的数据的大小,以便在其前面加上大小前缀。大小可以是字节、字、双字。您正在比较单个字符,因此大小为字节。代码应该是这样的
    cmp字节[op],“+”
  • 如果您有一个变量并且执行了
    mov eax,varname
    这会将varname的地址移动到eax。如果要移动varname的内容,必须用方括号括起来,如
    mov eax、[varname]
    。处理字符串地址和打印字符串例程时,需要在EAX中传递字符串的地址,而不是内容。因此,去掉括号
  • 如果使用
    call
    调用函数,则函数应以
    ret
    结束
  • 不要
    jmp
    调用函数,使用
    call
  • 如果要打印字符,请不要使用打印字符串,请使用打印字符。将角色放置在EAX中
  • 如果要打印整数,请不要使用print\u string,请使用print\u int。将整数放入EAX中
修订守则如下:

;program to add, multiply, or give the power of a number

%include "asm_io.inc"

segment .data

prompt1 db    "Enter a number: ", 0        ;prompts
prompt2 db    "Enter another number: ", 0
prompt3 db    "Enter an operand", 0
prompt4 db    "OP ", 0    ;idiotic prompts for printing
prompt5 db    " = ", 0    ;another printing prompt

segment .bss

num1  resd 1    ;variable for 1st number
num2  resd 1    ;variable for 2nd number
op    resd 1    ;variable for operand


segment .text

    global  asm_main
asm_main:
    enter   0,0                 ; setup routine
    pusha

    restart:
        mov     eax, prompt1    ; print out prompt
        call    print_string
        call    print_nl

        call    read_int        ; read integer
        mov     [num1], eax     ; store into num1
        call    print_nl

        mov     eax, prompt2    ; print out prompt
        call    print_string
        call    print_nl

        call    read_int        ; read integer
        mov     [num2], eax     ; store into num2
        call    print_nl

        mov     eax, prompt3    ;print out prompt
                                ;*** Typo - promtp3 changed to prompt3
        call    print_string
        call    print_nl

        call    read_char       ;read operand and dispose of null
        call    read_char
        mov     [op], eax       ;store operand in [op]
        call    print_nl

        cmp     byte [op], '*'  ;operand comparison
                                ;*** We must specify the size of data we are
                                ;*** comparing, so we tell the assembler that
                                ;*** with 'byte' in front of the variable
        jne     jmp1
        call    mulFun
        jmp     restart

jmp1:   cmp     byte [op], '+'  ;operand comparison
                                ;*** We must specify the size of data we are
                                ;*** comparing, so we tell the assembler that
                                ;*** with 'byte' in front of the variable
        jne     jmp2
        call    sumFun
        jmp     restart

jmp2:   cmp     byte [op], '^'  ;operand comparison
                                ;*** We must specify the size of data we are
                                ;*** comparing, so we tell the assembler that
                                ;*** with 'byte' in front of the variable
        jne     jmp3
;        call    expFun         ;*** This expFun function doesn't exist so
                                ;*** don't call it so we can compile and link
        jmp     restart

jmp3:   cmp     byte [op], 'e'  ;exit function
                                ;*** We must specify the size of data we are
                                ;*** comparing, so we tell the assembler that
                                ;*** with 'byte' in front of the variable
        je      end1

end1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    call    print_nl          ; pr
    popa
    mov     eax, 0            ; return back to C
    leave
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mulFun:                     ;multiplication function
                            ;*** NASM is case sensitive - changed mulfun to mulFun
    mov     ebx, [num1]
    mov     ecx, [num2]
    imul    ebx, ecx
    call    printFun        ;*** Call printFun, don't 'jmp' to it
    ret                     ;*** Since mulfun was called, we use 'ret' to return

sumFun:                     ;sum function
    mov     ebx, [num1]
    mov     ecx, [num2]
    add     ebx, ecx
    call    printFun
    ret

printFun:                   ;printing function
    mov     eax, prompt4    ;*** We want the address of prompt4, not what is at prompt4
                            ;*** Remove the brackets from [prompt4]
    call    print_string
    mov     eax, [num1]
    call    print_int       ;*** Use print_int to print an integer, not print_string
    mov     eax, [op]
    call    print_char      ;*** Use print_char to print a char, not print_string
    mov     eax, [num2]
    call    print_int       ;*** Use print_int to print an integer, not print_string
    mov     eax, prompt5    ;*** We want the address of prompt5, not what is at prompt5
                            ;*** Remove the brackets from [prompt5]
    call    print_string
    mov     eax, ebx
    call    print_int       ;*** Use print_int to print an integer, not print_string;
    call    print_nl
    ret
我将把开发expFun功能的任务留给原始海报。目前,我已经注释掉了它,以便可以组装、链接和运行现有代码

您可以使用printf,但我认为这条漫长的道路也可以教会您一些东西,我的回答中排除了对printf的讨论。你的导师、课程材料、助教是开始问其他问题的好地方


提供此答案是为了使您的程序进入可用状态,以便您可以继续执行作业。在我看来,原来的问题太宽泛了。如果需要进一步的帮助,最好问一个新问题和具体问题。

此外,我希望更好地使用本网站,因此,我将非常感谢您为我提供的任何格式错误、一般发布指南或提示。首先,您需要确切地解释您的代码现在做了什么,在哪里失败,你期望它做什么。其次,在汇编语言中编写代码比使用你提到的任何高级语言都要枯燥得多-现在没有一个头脑正常的人会完全用汇编语言编写复杂的代码-但这是所有东西最终编译的结果,所以至少从表面上了解它是很好的。这个网站是为书呆子准备的,所以,告诉我们你很紧张或感激是多余的。您可以跳过该选项。:-)在评估编译器对代码所做的操作时,能够阅读汇编语言非常有用。编写程序集非常昂贵,因此现在很少做,除非在非常专业的环境中。我想我的主要问题是打印'op5*6=30',如果是C,它将只使用'printf(“OP%d%C%d=%d)”,num1,op1,num2,product;'我不知道如何在Assembly中打印,显然您使用的是
asm_io.inc
,它为您提供了基本的输入输出帮助。因此,请使用它提供的任何东西,一个接一个地打印部件,例如
调用write_char
write_int
write_string
(在适当的参数中使用您真正拥有的函数).谢谢Michael,我确实解决了我的问题,你对这个问题的回答是正确的。我在网上上课,所以当一个视频没有详细介绍printf之类的内容时,它会在我和程序之间制造障碍。我问得不太清楚,这显然会影响我正确回答问题的机会,但你的回答是:他给我指出了正确的方向。