Windows 汇编寄存器
我的问题是尽可能多地获取关于注册的信息……运气不好:/Windows 汇编寄存器,windows,assembly,cpu-registers,Windows,Assembly,Cpu Registers,我的问题是尽可能多地获取关于注册的信息……运气不好:/ 每个人都犯了大错[可能是因为英语不是我的母语]。 所以,这个问题将更一般化;( 我需要一个基础教程! 啊……我能不能说得更具体一点? 另外,提前感谢您的帮助!一般来说,您可以使用eax、ebx、ecx、edx、esi和edi中的任意一种。它们都可以保存任何32位值 请记住,如果调用任何Win32 API函数,它们可以自由修改eax、ecx和edx。因此,如果需要在函数调用中保留这些寄存器的值,则必须将它们临时保存在某个位置(例如堆栈上)。
每个人都犯了大错[可能是因为英语不是我的母语]。 所以,这个问题将更一般化;(
我需要一个基础教程!
啊……我能不能说得更具体一点?
另外,提前感谢您的帮助!一般来说,您可以使用
eax
、ebx
、ecx
、edx
、esi
和edi
中的任意一种。它们都可以保存任何32位值
请记住,如果调用任何Win32 API函数,它们可以自由修改eax
、ecx
和edx
。因此,如果需要在函数调用中保留这些寄存器的值,则必须将它们临时保存在某个位置(例如堆栈上)。类似地,如果您编写的函数将由另一个函数调用(例如Windows回调),则应在该函数中保留
ebx
、esi
、edi
和ebp
有些指令是硬编码的,以使用某些寄存器。例如,循环
指令使用(e)cx
,字符串指令使用esi
/edi
,div
指令使用eax
/edx
,等等。通过查看中所有指令的描述,您可以找到所有此类情况。寄存器的“固定用途”源自8086天的古老根源(在某些方面,甚至在那之前)
8086是一台累加器机器,你应该主要用ax
(现在还没有eax
),还有一点用dx
。你可以在许多指令中看到这一点,例如,大多数ALU操作都有一个较小的op ax,imm
(还有op al,imm
)与opother相比,imm和古老的十进制数学指令(daa
和friends)只在al
上运行。有些指令总是将(e)ax
和(e)dx
引用为“高半”,请参见“旧乘法”(使用单显式操作数),imul
在80186中添加了立即数,imul reg,r/m
在80386中添加了大量内容,包括32位模式。32位模式还带来了现代ModRM/SIB结构,这是旧版本和现代版本。在旧版本中,只有4个寄存器可用于一个内存操作数,所以又有一点“寄存器的固定角色”。32位模式基本上删除了这一点,除了esp
永远不能成为索引寄存器(这通常是没有意义的)
最近,Haswell引入了shlx
,它取消了只能使用cl
作为计数进行可变量移位的限制,并且mulx
部分取消了“宽乘法”寄存器的固定角色(80186和80386仅添加了“通用”部分)没有高半部的乘法形式,mulx
仍然赋予edx
一个固定的角色
更奇怪的是,最近添加的pblendvb
为xmm0
分配了一个固定角色,在此之前,向量寄存器没有受到这种老式的限制。不过,这个固定角色在AVX中消失了,AVX允许对额外的操作数进行编码。pcmpistri
和friends仍然分配一个但已将角色固定为ecx
x64将8位寄存器操作数更改为8位寄存器操作数,如果存在REX前缀,则现在可以使用以前不可编码的spl
、bpl
、sil
和dil
,但代价是能够寻址ah
、ch
、dh
或bh
。这可能是mov的症状由于以前使用bpl
,它没有多大意义,但现在它“更通用”,它可能有一些用途(尽管它仍然经常被用作基本指针)
一般的模式是减少限制/固定角色。但x86的大部分历史至今仍清晰可见。作为一般性评论,在进一步讨论之前,我建议您采用一种编程风格,否则您会发现很难遵循自己的代码。下面是一个格式化的代码示例,可能并非所有内容都正确格式化,但它会给你一个想法。一旦养成习惯,这比编写乱七八糟的代码要容易。它的主要优点之一是,通过练习,你可以将目光投向代码,并且比阅读每一行都要快得多
.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
不要使用注释来解释指令的作用:使用注释来说明您试图实现的内容,或者寄存器代表的内容,从而为代码增加附加值
祝你好运:大量的练习和夜班!我不知道你在问什么,只是含糊不清的“用CPU寄存器的代码回答我并写下细节”,其范围太广,无法在此处回答。请花几分钟时间阅读,然后你的问题清楚地解释你发布的代码存在的问题,并提出与该代码相关的具体问题以及我们可以为你回答的问题。试试你管,这是大量的教程=你的意思是什么“如何使用它们”?只需在说明中使用它们的名称。@Jose Manuel啊。。我从来没有想到过。。我只想到了可打印的教程。我正在观看。。我希望它能解释一些关于寄存器的内容。可打印?这不是个好主意,纸张来自树木(我是说,真正的树木)。不要打印,保护自然。我认为“高水平”是错误的吗“asm编译器遵循WIN32 ABI,只要您指定约定。即,除非您