●●●eax,ebx,ecx,edx等等寄存器书上讲得太抽象了?有些不懂,或者是理解错误的地方,请大家指点

etracer 2009-07-14 08:11:53
书上说,AX累加器,bx,cx,dx是通用寄存器,分别用作基址变址,
计数器,数据,那么eax,ebx,ecx,edx也分别是累加器,基址变址,计数器,数据 吧?

基址变址:是什么意思?
下面代码为什么GetModuleHandle的返回值默认在eax里面,不在edx,ebx,ecx里面呢?eax是累加器,难道说累加器,
是专门得到函数的返回值得么?
-----------------------------------------------------
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
-----------------------------------------------------------------
又如下面代码,怎么又把数据村到esi里面了,原来都是存在eax里面的?
又突然冒来个push ebp? ebp又是做什么的?还有就是mov fs:[0],esp这句话也不懂。
即便看了教材,也对应不上这寄存器的含义,书上讲得太抽象了?麻烦各位给讲讲,谢谢了


--------------------------------------------------------------
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_INFO equ 1001
IDM_MAIN equ 2000
IDM_OPEN equ 2001
IDM_EXIT equ 2002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hRichEdit dd ?
hWinMain dd ?
hWinEdit dd ?
szFileName db MAX_PATH dup (?)

.const
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szFont db '宋体',0
szExtPe db 'PE Files',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
db 'All Files(*.*)',0,'*.*',0,0
szErr db '文件格式错误!',0
szErrFormat db '这个文件不是PE格式的文件!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_AppendInfo proc _lpsz
local @stCR:CHARRANGE

pushad
invoke GetWindowTextLength,hWinEdit
mov @stCR.cpMin,eax
mov @stCR.cpMax,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
popad
ret

_AppendInfo endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include _ProcessPeFile.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @stCf:CHARFORMAT

invoke GetDlgItem,hWinMain,IDC_INFO
mov hWinEdit,eax
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret

_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext

pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push [eax + 0ch]
pop [edi].regEbp
push [eax + 8]
pop [edi].regEip
push eax
pop [edi].regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret

_Handler endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_OpenFile proc
local @stOF:OPENFILENAME
local @hFile,@dwFileSize,@hMapFile,@lpMemory

invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szExtPe
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if ! eax
jmp @F
.endif
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile,eax
invoke GetFileSize,eax,NULL
mov @dwFileSize,eax
.if eax
invoke CreateFileMapping,@hFile,NULL,PAGE_READONLY,0,0,NULL
.if eax
mov @hMapFile,eax
invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
.if eax
mov @lpMemory,eax
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
assume fs:nothing
push ebp
push offset _ErrFormat
push offset _Handler
push fs:[0]
mov fs:[0],esp
;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
mov esi,@lpMemory
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp _ErrFormat
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _ErrFormat
.endif
invoke _ProcessPeFile,@lpMemory,esi,@dwFileSize
jmp _ErrorExit
_ErrFormat:
invoke MessageBox,hWinMain,addr szErrFormat,NULL,MB_OK
_ErrorExit:
pop fs:[0]
add esp,0ch
invoke UnmapViewOfFile,@lpMemory
.endif
invoke CloseHandle,@hMapFile
.endif
invoke CloseHandle,@hFile
.endif
.endif
@@:
ret

_OpenFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
call _Init
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDM_OPEN
call _OpenFile
.elseif ax == IDM_EXIT
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke LoadLibrary,offset szDllEdit
mov hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke FreeLibrary,hRichEdit
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
...全文
5063 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
meimeiaiwa 2011-04-29
  • 打赏
  • 举报
回复
回复看内容~~
luwenjie66 2010-08-05
  • 打赏
  • 举报
回复
不错,正好是我想要找的~!收录下
promise_to_be 2010-03-25
  • 打赏
  • 举报
回复
呵呵。从百度收到进来的哈。。谢谢了。刚合适我现在正好不懂。。和lz一样
miaosiki 2010-01-21
  • 打赏
  • 举报
回复
好贴...mark
jgstudy 2010-01-05
  • 打赏
  • 举报
回复
回复是为了阅读
kalaikaqu 2009-11-16
  • 打赏
  • 举报
回复
MARK2
incwar 2009-10-11
  • 打赏
  • 举报
回复
mark
deep_pro 2009-07-15
  • 打赏
  • 举报
回复
如果lz是从intel的51学到8086再学到IA32
就会发现累加器真是非常金贵的东西
甚至在51里加减乘除必须使用累加器,这个限制越往后就越松了

lz加油,慢慢就会理解了

建议配合一些编译原理的书,理解高级语言和汇编语言之间的接口和转换,就理解了
单看汇编,可能很久之后才有顿悟的感觉
推荐 《程序员的自我修养--连接、装载和库》
etracer 2009-07-15
  • 打赏
  • 举报
回复
感谢13楼的鼓励,同时也感谢12楼的回复,感觉12楼是我想找的答案,但是我的汇编基础不好,只懂了一部分。
另外每个回复的人都很感激,谢谢大家耐心的指导,谢谢了,我再看看书,研究一下,然后继续问,,呵呵呵
jxc25 2009-07-14
  • 打赏
  • 举报
回复
mov hInstance,eax
执行前eax很贵只有一个累加器
执行后eax很贱CPU有八个寄存器
cnzdgs 2009-07-14
  • 打赏
  • 举报
回复
在8086中,寄存器是ax、bx等,在386之后,寄存器扩展到了32位,eax的低16位就是ax,ebx的低16位是bx,原本的16位寄存器都可以继续使用,以字母e开头表示使用32位寄存器。32寄存器的用法与16位类似,例如32位程序用ecx做记数器,主要一点差异是,32位程序中任意通用寄存器均可用做间址和变址。在X64处理器中,用rax、rbx表示64位寄存器,eax表示rax的低32位,ax表示rax的低16位。
在32位程序中,32位以内的函数返回值都通过eax寄存器来传递。
fs是386之后增加的段寄存器,在Windows应用程序中,fs:[0]用来保存异常捕获设置。
jxc25 2009-07-14
  • 打赏
  • 举报
回复
可以mov hInstance,EBX
不过将来不能用??? eax,???了
用了就成一bug
etracer 2009-07-14
  • 打赏
  • 举报
回复
那么,函数的返回值,还有函数的参数,一般、用那个寄存器呢?
另外问个问题,代码中的
invoke GetModuleHandle,NULL
mov hInstance,eax
执行后GetModuleHandle 我不去,eax 取值,
我去
mov hInstance,EBX取值,也可以么?因为5楼的回答(可能我理解有问题,别介意)

另外重复问一下我4楼的问题
BAYNPU 2009-07-14
  • 打赏
  • 举报
回复
1、变址寄存器
32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响
高16位的数据。
寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特
殊的功能。
2、指针寄存器
32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影
响高16位的数据。
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
它们主要用于访问堆栈内的存储单元,并且规定:
BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;
SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。
BAYNPU 2009-07-14
  • 打赏
  • 举报
回复
在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,但在32位CPU中,其32位
寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,
所以,这些32位寄存器更具有通用性。
etracer 2009-07-14
  • 打赏
  • 举报
回复
我是新手,能再简单的讲一下么,没看懂,那我可以这么理解么,程序的返回值都放在累加器里面么?八个寄存器eax,ebx,ecx,edx,esp,ebp,esi,edi 干什么用都可以么?


书上说,AX累加器,bx,cx,dx是通用寄存器,分别用作基址变址,
计数器,数据,那么eax,ebx,ecx,edx也分别是累加器,基址变址,计数器,数据 吧?

基址变址:是什么意思?
下面代码为什么GetModuleHandle的返回值默认在eax里面,不在edx,ebx,ecx里面呢?eax是累加器,难道说累加器,
是专门得到函数的返回值得么?

怎么又把数据村到esi里面了,原来都是存在eax里面的?
又突然冒来个push ebp? ebp又是做什么的?还有就是mov fs:[0],esp这句话也不懂。
即便看了教材,也对应不上这寄存器的含义,书上讲得太抽象了?麻烦各位给讲讲,谢谢了
pla_007 2009-07-14
  • 打赏
  • 举报
回复
高级语言特性+编译器,通常将函数的返回值放在EAX中(单一返回值直接放EAX,如果多个返回值,则EAX中存放指针)。

至于寻址方式,你可以随便找本汇编的教材看一下,看过之后,看的懂寻址寻到哪个地址就行了。
至于具体是属于哪种寻址方式,就没必要深究了。
jxc25 2009-07-14
  • 打赏
  • 举报
回复
eax贵到你不敢用
00000000`0223ff68 90 nop
00000000`0223ff69 91 xchg eax,ecx
00000000`0223ff6a 92 xchg eax,edx
00000000`0223ff6b 93 xchg eax,ebx
00000000`0223ff6c 94 xchg eax,esp
00000000`0223ff6d 95 xchg eax,ebp
00000000`0223ff6e 96 xchg eax,esi
00000000`0223ff6f 97 xchg eax,edi
jxc25 2009-07-14
  • 打赏
  • 举报
回复
x86里只有一个累加器eax和八个寄存器eax,ebx,ecx,edx,esp,ebp,esi,edi
所有这个eax很贵,这个esi很贱
gp341 2009-07-14
  • 打赏
  • 举报
回复
你的理解有问题 api函数规定默认是是用eax返回值 所以大家一般都遵守这个规定
所以自己写的函数一般也是如此 即使值在其他寄存器 比如
myStrlen proc uses ebx edi esi _lpOut

.....
mov eax, ebx 返回值放在eax
ret
myStrlen endp
除了寄存器EBP、ESP用于指令外, 其他寄存器都可以随便使用, 不一定按照书上说的功能那样用
加载更多回复(1)

21,498

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧