了解Y86

时间:2016-10-28 18:26:26

标签: assembly y86

我有以下代码。有人可以解释我在括号中的问题吗?

# Execution begins at address 0 (why?)
.pos 0
irmovq stack, %rsp  # Set up stack pointer  (how can i move the word "stack" in rsp)
call main   # Execute main program
halt    # Terminate program  

# Sample linked list   (what is the purpose of .align 8?)
.align 8
ele1:
.quad 0x00a
.quad ele2
ele2:
.quad 0x0b0
.quad ele3
ele3:
.quad 0xc00
.quad 0

main:
irmovq ele1,%rdi
call sum
ret


sum:


# Stack starts here and grows to lower addresses
.pos 0x100
stack:

2 个答案:

答案 0 :(得分:2)

.pos <adr>是更改编译器当前虚拟地址的指令。因此,编译的下一条指令将被视为地址<adr>,如果您将<label>置于其前面,<label>将具有值<adr>,因此任何指令都会在使用<label>的绝对地址运行的代码将使用<adr>值进行编译。

此外,编译器会在编译期间跟踪当前的虚拟地址,因此如果稍后使用一些<label2>指令,则其值为<adr + size_of_produced_machine_code_so_far>

当您在实际内存中的该位置加载机器代码时,代码中的所有绝对地址都适合并正常工作(如果您将其加载到别处,它将无法正常工作,因为说明仍将引用编译它们的<adr>

在您的示例中,这意味着,一旦将机器代码加载到内存计算机中,预计第一个irmovq将被放置在地址0

为什么执行从地址0开始?谁知道,这就是目标平台的特征。如果目标平台将从0x300开始执行,那么使用.pos 0x300指令将启动代码放在那里是有意义的。

  

irmovq stack, %rsp # Set up stack pointer (how can i move the word "stack" in rsp)

rsp设置为包含stack符号的地址(实际上它是“堆栈”符号的,可以看作人类逻辑中的内存地址,但它是只是数字,如计算机中的所有,这是0x100值(因为.pos指令正好在stack:标签定义之前)。因此该指令执行rsp = 0x100

  

.align 8的目的是什么?

对齐意味着调整地址,可以在没有余数的情况下以某个数字整除。在第一种情况下,标签ele1将具有可被8整除的地址。如果先前的机器代码将以某个不可分割的地址结束,则编译器将添加一些字节(通常为nop - 类似指令)以填充差距,直到下一个可能的地址满足align要求。

对齐对于内存控制器性能很重要,因为它们通常在内部使用字节组,就像只能从8对齐地址获取8字节的四字节一样。如果您要求它从非对齐地址获取四字,它将从(address & -8)((address & -8)+8)获取两个8字节集,并从这些取出的中间读取最后的8字节结果。字节。 (在x86 ..在其他平台上未对齐的内存访问甚至可以进行无效操作,导致CPU接收陷阱信号,在这种情况下运行崩溃处理程序)。

(为什么按位AND和-8使地址8对齐?-8 = 0xF..F8 = 0b11 ... 11000 =&gt;最后3位设置为0 =&gt;可被8整除)

答案 1 :(得分:1)

执行从0开始,因为这是.pos 0在下一行上执行的操作。

单词&#34; stack&#34;未被移动:stack它是代码中更下方的标签,它将堆栈指针rsp设置为内存中的该位置。

对齐8字节边界的目的是因为处理器不善于桥接这样的边界。 .quad指令生成8字节数据。

要求提供教程是不合适的主题 - 很容易谷歌,并选择一个你认为适合自己的教程。