我在此Y86汇编代码中正确理解了堆栈吗?
我已经创建了这个简单而毫无意义的汇编(Y86)代码,以了解我是否理解使用指令call,push,popl和ret时堆栈中发生的一切.
I've created this simple and pointless assembly (Y86) code to see if I understand everything that's happening in the stack when the instructions call, pushl, popl and ret are used.
就像我说的那样,这段代码毫无意义,仅用于测试/学习目的.虽然,所有内存地址都是正确的(希望的)计算,并且不是随机的.
Like I said, this code is pointless, it's just for testing/learning purposes. Although, all memory addresses were correctly (hopeful) calculated and are not random.
汇编代码如下:
| .pos 0
0x00 | irmovl Stack, %esp
0x06 | rrmovl %esp, %ebp
0x08 | irmovl $5, %eax
0x0E | call func
0x13 | halt
0x14 | func:
0x14 | pushl %ebp
0x16 | rrmovl %esp, %ebp
0x18 | pushl %eax
0x1A | popl %eax
0x1C | popl %ebp
0x1E | ret
| .pos 50
0x32 | Stack: .long 0
以下是我最好的画一个堆栈,并解释每个步骤(指令)如何处理堆栈.请注意,我使用SP和BP分别指%esp和%ebp,因为它们使用率很高,并且更易于阅读.
The following is my best to draw a stack and explain what each step (instruction) does with the stack. Please note that I used SP and BP to refer to %esp and %ebp respectively cause they are used a lot and makes it easier to read.
我想知道的是我是否掌握了所有一切,或者错过了什么.请随时复制/粘贴您想要的任何内容,并修正您的答案中的某些步骤.
What I want to know is if I got everything above right or if I missed anything. Please feel free to copy/paste whatever you want and fix some step(s) in your answer.
还请注意,我对此的理解非常重要,我周一有一个考试需要准备,我希望您能给我最好的答案.根据您的回答,我可能会(或不会)有一些相关的问题,我们将在评论部分进行处理.
Also note that my understanding of this is very important, I have an exam Monday for which I need to be prepared and I would like the best answer you can give me. Depending on your answers, I might (or not) have some related questions that we shall take care in the comments section.
- INSTRUCTION: irmovl Stack, %esp
- INSTRUCTION: rrmovl %esp, %ebp
1) Point %esp (SP) and %ebp (BP) to Stack
| ... |
0x2E |-------|
| |
0x32 |-------| <--- SP & BP
- INSTRUCTION: irmovl $5, %eax
1) Sets %eax = 5
- INSTRUCTION: call func
1) Decrements SP by 4 (0x32 -> 0x2E)
2) Saves return address (0x13) in memory location pointed by SP (0x2E)
3) Jumps to "func" memory address (0x14)
| ... |
0x2A |-------|
| 0x13 |
0x2E |-------| <--- SP
| |
0x32 |-------| <--- BP
- INSTRUCTION: pushl %ebp
1) Decrements SP by 4 (0x2E -> 0x2A)
2) Saves BP value (0x32) in memory location pointed by SP (0x2A)
| ... |
0x26 |-------|
| 0x32 |
0x2A |-------| <--- SP
| 0x13 |
0x2E |-------|
| |
0x32 |-------| <--- BP
- INSTRUCTION: rrmovl %esp, %ebp
1) Sets BP = SP (0x32 -> 0x2A)
| ... |
0x26 |-------|
| 0x32 |
0x2A |-------| <--- SP & BP
| 0x13 |
0x2E |-------|
| |
0x32 |-------|
- INSTRUCTION: pushl %eax
1) Decrements SP by 4 (0x2A -> 0x26)
2) Saves %eax value (5) in memory location pointed by SP (0x26)
| ... |
0x22 |-------|
| 5 |
0x26 |-------| <--- SP
| 0x32 |
0x2A |-------| <--- BP
| 0x13 |
0x2E |-------|
| |
0x32 |-------|
- INSTRUCTION: popl %eax
1) Saves value (5) in memory location pointed by SP (0x26) in %eax
2) Increments SP by 4 (0x26 -> 0x2A)
| ... |
0x22 |-------|
| 5 |
0x26 |-------|
| 0x32 |
0x2A |-------| <--- SP & BP
| 0x13 |
0x2E |-------|
| |
0x32 |-------|
- INSTRUCTION: popl %ebp
1) Saves value (0x32) in memory location pointed by SP (0x2A) in %ebp
2) Increments SP by 4 (0x2A -> 0x2E)
| ... |
0x22 |-------|
| 5 |
0x26 |-------|
| 0x32 |
0x2A |-------|
| 0x13 |
0x2E |-------| <--- SP
| |
0x32 |-------| <--- BP
- INSTRUCTION: ret
1) Jumps to memory address (0x13) in memory location pointed by SP (0x2E)
2) Increments SP by 4 (0x2E -> 0x32)
据我所知,一切正常.
我可以指出的一个小问题是,将地址写在这些地址的值之上可能更直观.那就是:
One minor point I can make is that it is probably more intuitive to write the addresses above the value at those addresses. That is:
0x2E |-------|
| 0x13 |
0x32 |-------|
原因是覆盖值(0x2E
,0x2F
,0x30
,0x31
)的地址范围指向下一个地址0x32
.
The reason being that the address range covering the value (0x2E
,0x2F
,0x30
,0x31
) goes towards the next address 0x32
.
当然,您可能希望在考试时使用老师期望的符号.
Of course, you might want to use the notation expected by your teacher when doing the exam.