【问题标题】:How to call a subprogram inside of another subprogram?如何在另一个子程序中调用一个子程序?
【发布时间】:2019-04-05 06:35:14
【问题描述】:

我最近开始了一个项目,该项目将用户输入的后缀表达式分别转换为前缀和中缀表达式。但是,我在其他子程序中调用这些子程序时遇到了问题,因为我不确定它们是如何工作的。我想做的是在 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 

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

【问题讨论】:

    标签: assembly x86 nasm function-call


    【解决方案1】:

    显然,如果您在函数调用周围使用pusha/popapopa 会破坏 EAX 中的返回值,并将其替换为调用之前 EAX 中的任何值。不要那样做。

    只需让函数破坏调用破坏的寄存器(i386 System V 调用约定1中的 EAX、ECX 和 EDX),并将这些寄存器用于临时或不需要的任何内容在函数调用中存活。


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      相关资源
      最近更新 更多