我正在编写一个汇编子例程来计算字符串的长度。
%include 'function.asm'
section .data
msg db 'Hello this is yogi', 0AH
section .text
global _start
_start:
mov esi, msg
push esi
call strlength
function.asm文件内部,
strlength:
pop eax
mov edi, eax
loop:
cmp byte[eax], 0
jz finished
inc eax
jmp loop
finished:
sub eax, edi
mov edx, eax
mov ecx, edi,
mov ebx, 1
mov eax, 4
int 80h
exit:
mov eax, 1
mov ebx, 0
int 80h
我只包括了相关部分。 简而言之,发生的事情是我已经在esi寄存器中传递了字符串“ msg”地址。然后,我将esi(字符串的地址)的内容压入堆栈。然后我调用了strlength子例程。
在子例程中,我弹出了eax中的地址,然后将该地址移至另一个寄存器“ edi”。到目前为止,一切都很好,并且程序运行良好。
问题是它首先如何工作?
当我将“ esi”推入堆栈时,这是要放置的第一件事,然后我调用了子例程,这意味着它的地址也将放置在堆栈中,然后当我使用pop命令时,为什么弹出字符串的地址,而不是子例程的地址。因为子例程的地址是在以后推送的,所以它应该在顶部,因此应该将其弹出?
我使用GDB确认相同,堆栈指针指向0x ******** 90,然后当我推送字符串的地址时,它开始指向0x ******** 8c,之后又指向我调用了子例程,将其更改为0x ******** 88。表示每次减少4个字节。 在子例程中,当我第一次使用pop时,它后来增加了4个字节,变为0x ******** 8c。
你们能帮我这个概念吗?我是否对堆栈的工作或其他方面感到误解。