我最近开始研究一个项目,该项目将用户输入的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
该程序用于将后缀转换为前缀并将其显示给用户。我需要帮助弄清楚如何调用这些子程序或如何使用它们才能获得正确的输出。
答案 0 :(得分:0)
很显然,如果在函数调用前后使用pusha
/ popa
,则popa
会破坏EAX中的返回值,并将其替换为调用前EAX中的值。不要那样做。
仅让函数破坏被调用阻塞的寄存器(i386 System V调用约定 1 中的EAX,ECX和EDX),然后将这些寄存器用于临时文件或不需要使用的任何文件在整个函数调用中生存下来。
脚注1:几乎所有其他32位x86调用约定。但是,如果您想查找有关如何传递args的更多详细信息(例如,传递给采用结构的函数),则可以查看C编译器输出,或查阅i386 System V ABI文档。