如何在另一个子程序中调用一个子程序?

时间:2019-04-05 06:35:15

标签: assembly x86 nasm function-call

我最近开始研究一个项目,该项目将用户输入的Postfix表达式分别转换为前缀和后缀表达式。但是,我不确定在其他子程序中调用这些子程序时会遇到问题,因为我不确定它们的功能。我想做的是在postfix_to_prefix子程序中调用strcat子程序,但是对我来说,我不知道该怎么做。

该项目是针对计算机体系结构课程的,到目前为止,我已经花费了大约10个小时尝试对如何编写程序进行个人研究,但是我没有找到为使其正常运行而必须做的事情,特别是在代码的操作标签中。

; A Subprogram that converts Postfix Prefix
segment .data
plus_sign   db ' + ', 0
minus_sign  db ' - ', 0
multiply    db ' * ', 0
divider     db ' / ', 0
parenthsf   db ' ( ', 0
parenthsb   db ' ) ', 0

segment .bss    
operand     resd 1
operators   resd 1

segment .text


postfix_to_infix:
    push    ebp
    mov     ebp, esp

    mov     eax, 0
    mov     esi, 0
    mov     edi, 0
    mov     ebx, [ebp + 8]                      ; ebx = infix
    mov     ecx, [ebp + 16]                     ; ecx = post_len
    mov     edx, [ebp + 12]                     ; edx = postfix

comparison:
    mov     al, [edx + esi]
    cmp     al, '+'
    je      operation
    cmp     al, '-'
    je      operation
    cmp     al, '*'
    je      operation
    cmp     al, '/'
    je      operation
    cmp     al, ' '
    je      opexit

    inc     esi
    push    eax
    loop    comparison


operation:
    mov     [operators], eax
    pop     eax
    mov     [operand], eax
    pop     eax

    ;This point here is what I specifically need to figure out...
    pusha
    push    dword[operand]  
    push    eax
    call    strcat
    add     esp,8
    popa


opexit:
    inc     esi
    loop    comparison

    pop ebx
    pop ebp
    ret



; A subprogram strcat appends the contents of one string to the end of another
; strcat(str1,str2)
; Result: str1= str1 + str2
; stored in str1
segment .bss
append_length   resd 1
read_length     resd 1
segment .text
strcat: 
    push    ebp                             ; 
    mov     ebp, esp                        ;
    mov     edx, [ebp+12]                   enter code here; what we want to append

    push    edx                             ;
    call    length_is                       ;
    add     esp, 4                          ;
    mov     [append_length], eax            ;
    mov     eax, 0                          ;

    mov     ebx, [ebp+8]                    ; original string str1

    push    ebx                             ;
    call    length_is                       ;
    add     esp, 4                          ;
    mov     [read_length], eax              ;
    mov     eax, 0                          ;

    mov     ebx, [ebp+8]                    ; original string str1
    mov     edx, [ebp+12]                   ; what we want to append
    mov     ecx, [append_length]            ;
    mov     edi, 0                          ;
    mov     esi, [read_length]              ; the last location of original string is where to append 

append_loop:
    mov     al, [edx+edi]                   ;
    mov     [ebx+esi], al                   ;
    add     esi, 1                          ;
    add     edi, 1                          ;
    loop    append_loop                     ;

    pop     ebp                             ;
    ret 

该程序用于将后缀转换为前缀并将其显示给用户。我需要帮助弄清楚如何调用这些子程序或如何使用它们才能获得正确的输出。

1 个答案:

答案 0 :(得分:0)

很显然,如果在函数调用前后使用pusha / popa,则popa会破坏EAX中的返回值,并将其替换为调用前EAX中的值。不要那样做。

仅让函数破坏被调用阻塞的寄存器(i386 System V调用约定 1 中的EAX,ECX和EDX),然后将这些寄存器用于临时文件或不需要使用的任何文件在整个函数调用中生存下来。


脚注1:几乎所有其他32位x86调用约定。但是,如果您想查找有关如何传递args的更多详细信息(例如,传递给采用结构的函数),则可以查看C编译器输出,或查阅i386 System V ABI文档。