大会登记册

时间:2015-05-13 14:25:54

标签: windows assembly cpu-registers

我的问题是关于尽可能多地获取关于注册的信息......没有运气:/
每个人都错了[可能是因为英语不是我的母语]。 所以,问题会更加笼统......;(
我需要一本BASICS教程! 啊......我可以更具体吗? 另外,感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

一般情况下,您可以根据需要使用eaxebxecxedxesiedi中的任意一种。它们每个都可以保存任何32位值。

请注意,如果您调用任何Win32 API函数,他们可以自由修改eaxecxedx。因此,如果您需要在函数调用中保留这些寄存器的值,则必须暂时将它们保存在某处(例如,在堆栈中)。
同样,如果你编写一个要被另一个函数调用的函数(例如Windows回调),你应该在该函数中保留ebxesiediebp

某些指令被硬编码以使用某些寄存器。例如,loop指令使用(e)cx,字符串指令使用esi / edidiv指令使用eax / {{1您可以通过查看Intel's manual中所有说明的说明找到所有此类案例。

答案 1 :(得分:1)

寄存器的“固定用途”源自8086天的古老根源(在某些方面,甚至在此之前)。

8086是一个累加器机器,你应该主要用ax进行数学运算(还没有eax),还有dx。您可以在许多说明中看到这一点,例如,大多数ALU操作都有op ax, imm(也是op al, imm)的小于op other, imm的形式,以及古老的十进制数学指令({{1和朋友)只在daa上运行。有些指令总是引用al,也许(e)ax作为“高半”,请参阅“旧的乘法”(使用单个显式操作数),(e)dx中添加了一个立即数80186,imul被添加到80386中,增加了很多东西,包括32位模式。 32位模式也出现了现代ModRM / SIB结构,这里是旧的16bit版本和现代32/64bit版本。在旧版本中,只有4个寄存器可以在内存操作数中使用,所以再次有一些“寄存器的固定角色”。除了imul reg, r/m永远不能成为索引寄存器(通常不会有意义)之外,32位模式大多被删除了。

最近,Haswell引入了esp,它消除了只能使用shlx作为计数来进行变量变换的限制,cl部分删除了寄存器的固定角色对于“宽乘法”(80186和80386仅添加了“一般”形式的乘法而没有高一半),mulx仍然赋予mulx一个固定的角​​色。

更奇怪的是,最近添加的edxpblendvb分配了一个固定的角​​色,在此之前,向量寄存器并没有受到这种老式限制的阻碍。然而,固定角色在AVX中消失了,这允许对额外操作数进行编码。 xmm0和朋友们仍然会将固定角色分配给pcmpistri

x64改为8位寄存器操作数,如果存在REX前缀,现在可以使用ecxsplbplsil,以前无法解决,但代价是能够处理dilahchdh。这可能是摆脱特殊角色的一个症状,因为以前使用bh没有多大意义,但现在它“更通用”它可能有一些用途(它仍然是通常用作基指针。)

一般模式是减少限制/固定角色。但是x86的大部分历史今天仍然可见。

答案 2 :(得分:0)

作为一般性评论,在你走得更远之前,我建议采用编程风格,否则你会发现很难遵循自己的代码。下面是您的代码的格式化示例,也许并非所有内容都已正确格式化,但它为您提供了一个想法。一旦养成这种习惯,它就比制作符合条件的代码更容易了。它的一个主要优点是,通过练习,您可以将注意力放在代码上,并且比您必须阅读每一行更快地遵循它。

    .386
    .model flat, stdcall

    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\masm32.inc
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\masm32.lib

    .data

ProgramText db      "Hello World!", 0
BadText     db      "Error: Sum is incorrect value", 0
GoodText    db      "Excellent! Sum is 6", 0
Sum         sdword  0

    .code

start:
                            ;                         eax
    mov     ecx, 6          ; set the counter to 6    ?
    xor     eax, eax        ; set eax to              0
_label:
    add     eax, ecx        ; add the numbers         ?
    dec     ecx             ; from 0 to 6             ?
    jnz     _label          ;                         21
    mov     edx, 7          ;                         21
    mul     edx             ; multiply by 7           147
    push    eax             ; pushes eax into the stack
    pop     Sum             ; pops eax and places it in Sum
    cmp     Sum, 147        ; compares Sum to 147
    jz      _good           ; if they are equal, go to _good
_bad:
    invoke  StdOut, addr BadText
    jmp     _quit
_good:
    invoke  StdOut, addr GoodText
_quit:
    invoke  ExitProcess, 0

    end     start

我会挑出一行:

push    eax             ; pushes eax into the stack

不要使用注释来解释指令的作用:使用它们来说明你想要实现什么,或者寄存器代表什么,以便为代码增加价值。

祝你好运:充足的练习和午夜的油!