回 帖 发 新 帖 刷新版面

主题:汇编语言的准备知识(1)

汇编语言和CPU以及内存,端口等硬件知识是连在一起的. 这也是为什么汇编语言没有通用性的原因. 下面简单讲讲基本知识(针对INTEL x86及其兼容机)
============================
x86汇编语言的指令,其操作对象是CPU上的寄存器,系统内存,或者立即数. 有些指令表面上没有操作数, 或者看上去缺少操作数, 其实该指令有内定的操作对象, 比如push指令, 一定是对SS:ESP指定的内存操作, 而cdq的操作对象一定是eax / edx.

在汇编语言中,寄存器用名字来访问. CPU 寄存器有好几类, 分别有不同的用处:

1. 通用寄存器:
EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP(这个虽然通用,但很少被用做除了堆栈指针外的用途)

这些32位可以被用作多种用途,但每一个都有"专长". EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器. EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址. ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器. EDX是...(忘了..哈哈)但它总是被用来放整数除法产生的余数. 这4个寄存器的低16位可以被单独访问,分别用AX,BX,CX和DX. AX又可以单独访问低8位(AL)和高8位(AH), BX,CX,DX也类似. 函数的返回值经常被放在EAX中.

ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:

push ebp ;保存当前ebp
mov ebp,esp ;EBP设为当前堆栈指针
sub esp, xxx ;预留xxx字节给函数临时变量.
...

这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.

ESP 专门用作堆栈指针.

2. 段寄存器:
CS(Code Segment,代码段) 指定当前执行的代码段. EIP (Instruction pointer, 指令指针)则指向该段中一个具体的指令. CS:EIP指向哪个指令, CPU 就执行它. 一般只能用jmp, ret, jnz, call 等指令来改变程序流程,而不能直接对它们赋值.
DS(DATA SEGMENT, 数据段) 指定一个数据段. 注意:在当前的计算机系统中, 代码和数据没有本质差别, 都是一串二进制数, 区别只在于你如何用它. 例如, CS 制定的段总是被用作代码, 一般不能通过CS指定的地址去修改该段. 然而,你可以为同一个段申请一个数据段描述符"别名"而通过DS来访问/修改. 自修改代码的程序常如此做.
ES,FS,GS 是辅助的段寄存器, 指定附加的数据段.
SS(STACK SEGMENT)指定当前堆栈段. ESP 则指出该段中当前的堆栈顶. 所有push/pop 系列指令都只对SS:ESP指出的地址进行操作.

3. 标志寄存器(EFLAGS):

该寄存器有32位,组合了各个系统标志. EFLAGS一般不作为整体访问, 而只对单一的标志位感兴趣. 常用的标志有:

进位标志C(CARRY), 在加法产生进位或减法有借位时置1, 否则为0.
零标志Z(ZERO), 若运算结果为0则置1, 否则为0
符号位S(SIGN), 若运算结果的最高位置1, 则该位也置1.
溢出标志O(OVERFLOW), 若(带符号)运算结果超出可表示范围, 则置1.

JXX 系列指令就是根据这些标志来决定是否要跳转, 从而实现条件分枝. 要注意,很多JXX 指令是等价的, 对应相同的机器码. 例如, JE 和JZ 是一样的,都是当Z=1是跳转. 只有JMP 是无条件跳转. JXX 指令分为两组, 分别用于无符号操作和带符号操作. JXX 后面的"XX" 有如下字母:

无符号操作: 带符号操作:
A = "ABOVE", 表示"高于" G = "GREATER", 表示"大于"
B = "BELOW", 表示"低于" L = "LESS", 表示"小于"
C = "CARRY", 表示"进位"或"借位" O = "OVERFLOW", 表示"溢出"
S = "SIGN", 表示"负"
通用符号:
E = "EQUAL" 表示"等于", 等价于Z (ZERO)
N = "NOT" 表示"非", 即标志没有置位. 如JNZ "如果Z没有置位则跳转"
Z = "ZERO", 与E同.

如果仔细想一想,就会发现 JA = JNBE, JAE = JNB, JBE = JNA, JG = JNLE, JGE= JNL, JL= JNGE, ....

4. 端口

端口是直接和外部设备通讯的地方。外设接入系统后,系统就会把外设的数据接口映射到特定的端口地址空间,这样,从该端口读入数据就是从外设读入数据,而向外设写入数据就是向端口写入数据。当然这一切都必须遵循外设的工作方式。端口的地址空间与内存地址空间无关,系统总共提供对64K个8位端口的访问,编号0-65535. 相邻的8位端口可以组成成一个16位端口,相邻的16位端口可以组成一个32位端口。端口输入输出由指令IN,OUT,INS和OUTS实现,具体可参考汇编语言书籍。

回复列表 (共153个回复)

131 楼

嵌入式软件家教

未来五年内,国内Linux嵌入式软件开发的人才缺口达到120万,而目前熟练的Linux应用人才只有3000名。这意味着各大跨国公司及国内家电巨头都面临着人才严重短缺的挑战。”新华科技南京系统软件有限公司总经理王自强曾经这样说过。嵌入式软件开发人才的缺乏也带来了这个行业可观的薪酬待遇,嵌入式软件的从业者薪酬比其他IT业同行大约高出50%,初入门的开发人员平均月薪一般都能达到5000元,有三年以上经验的人员年薪都在 10万元以上,有10年工作经验的高级嵌入式软件工程师年薪在30万元左右。尽管待遇可观,可是相关企业还是很难招到合适的员工。

教师介绍: 陈老师,海归,新西兰梅西大学电子工程系毕业.资深研发工程师,精通bootloaded 精通linux核, 多年来一直从事Linux内核和应用的研发, ,熟悉s3c44box ,s3c2410,intel xscale等处理器。

以下所有一套体系课程加在一起只有4500元钱,总的时间加起来有连续一个月,(俱体情况要视学生本身情况而定)相比较其他的培训公司最大的优势是只招收4人左右,多了也不招,而且也要保证学生的质量,差的学生也不招,因为嵌入式软件也不是普通人能做的,充分保证了一对一的教学的时间.而且实验室设备也比其他培训公司要好得多.我之所以放弃公司高薪的工作,最重要的原因是我喜欢自由,更喜欢做老师,因为能教出来一个好的学生成就感比什么都强.还有上海以外的学员免费提供住宿一个月!!
联系电话 张小姐:021-50835796  QQ:568401154  MSN:lswatchly@hotmail.com
第一部分ARM课程
嵌入式处理器概述, ARM体系结构, ARM指令分类及其寻址方式,ARM程序设计, ARM C/C++混合编程, 
ADS的使用,ARM开发调试环境的建立,S3C2410A处理器体系结构 S3C2410A中断控制器  S3C2410A看门狗控制器,S3C2410A处理器定时器,S3C2410A串口控制器 S3C2410A实时时钟控制器 ,S3C2410A IIC总线控制器,S3C2410A flash应用,S3C2410A LCD控制器, S3C2410A触摸屏控制器, S3C2410A ADC控制器
所有以上的课程都包含用arm仿真器在线调试。
Linux系统驱动开发课程
系统开发课程
bootloader的移植,内核的移植,根文件系统的制作和移植,Redhat Linux 9虚拟机环境,安装开发工具和文件,配置超级终端/minicom,配置TFTP网络服务,引导目标板启动Linux内核,交叉编译应用程序, 交叉调试应用程序。开发系统引导程序, Bootloader介绍, s3c2410 bootloader 的编译使用,s3c2410 bootloader源码分析     s3c2410 bootloader移植过程.. 配置编译Linux内核,Linux内核介绍,Linux内核特点, Linux内核源代码结构,Linux内核选项解析,Linux内核编译链接。嵌入式Linux开发环境构建,交叉开发环境介绍,编译交叉开发工具链,配置主机开发环境,建立交叉开发环境,编译器和二进制工具详解,交叉调试应用程序。 Linux内核的打印函数,Linux内核启动过程错误分析,常用调试方法和工具。
   
驱动开发课程
 Linux设备驱动程序基础知识,系统调用和设备IO,字符设备驱动程序实现框架,阻塞与非阻塞IO设计用ioctl控制驱动程序,典型的字符设备驱动程序分析  。
Linux内存管理机制, 内存分配与存储器映射,高速缓存管理, mmap设备操作,在内核中描述时间
使用任务队列,内核定时器,硬件中断处理流程, Linux内核中断子系统,安装中断处理程序,上半部/下半部处理,中断共享。块设备特点及驱动程序工作原理, 块设备驱动与文件系统接口,块设备中的访问优化原理——请求队列与缓冲区,典型的块设备驱动程序分析, IDE设备块驱动程序框架,MTD Flash块设备驱动程序,Linux中存储卡驱动分析,嵌入式文件系统
OSI网络参考模型,. 套接字(socket)简介,套接字缓冲区(sk_buff),. net_device结构分析,数据包传送与接收,网络驱动的中断处理,以太网MAC地址解析。
USB主机驱动程序, USB设备驱动程序, USB HUB驱动程序, OHCI HCDPCI总线概述 PCI配置空间
PCI设备驱动结构
嵌入式显示设备简介,帧缓冲(framebuffer)设备特点. 帧缓冲驱动程序显示原理,帧缓冲驱动程序与DMA配合。
    
嵌入式linux 应用课程
Linux简介及历史,安装Linux操作系统, Linux基本命令,函数库和系统调用,嵌入式系统开发流程
如何选择嵌入式操作系统,认识gcc编译器,认识gdb调试器,Makefile祥解,vi编辑器高级使用,库和头文件的保存位置,共享库及其相关配置,使用和创建函数库,什么是交叉编译, 完整交叉编译环境的建立,
ISO/OSI七层协议模型/IP网络4层模式, TCP/IP协议族, TCP/IP编程, 基于嵌入式Linux的TCP/IP网络结构,基于嵌入式Linux的socket编程,UDP与TCP的区别, UDP Server-Client关系。
GUI基础知识,qt简介,建立Qt/Embedded 开发环境,编写qt程序。Linux文件系统概述, MTD技术分析,制作cramfs文件系统。

实验项目: 
在没有嵌入式linux操作系统下ARM程序的实验. (arm仿真器在线调试)
串口试验,蜂鸣器试验,实时时钟试验,ADC 试验,小键盘试验,触摸屏试验,LCD 试验, 640*480 VGA 试验,红外线试验,CAN 总线试验,IIC 试验,音频输出试验,SD 卡试验,CF卡读写试验。
嵌入式linux系统试验
熟悉Redhat Linux 9虚拟机环境,安装开发工具和文件, 配置超级终端/minicom, 配置TFTP网络服务,配置NFS网络服务,引导目标板启动Linux内核, 交叉编译应用程序,交叉调试应用程序. 配置编译s3c2410 bootloaded. 配置交叉开发环境,熟悉菜单配置文件的组织结构,熟悉内核配置过程选项 ,编译交叉开发环境所需要的内核. 制作最小的文件系统,部署cramfs文件系统
        
嵌入式linux驱动试验
字符驱动试验,块设备驱动试验,cs8900网卡驱动试验.usb 存贮驱动试验, SD 卡驱动试验,按键中断试验,led驱动试验,串口驱动试验,CF 卡驱动试验,LCD 驱动试验
嵌入式linux应用试验
Tcp udp client 和 server 端的程序编写.Daemon 进程的编写.多进程之间的通信编程. Qt embedded 图形界面的完整交叉编译,以及移植.

132 楼

好啊 我也想学点

133 楼


[em2]好啊

134 楼

想学汇编,顶一个

135 楼

太少了,跟没有说差不多.

136 楼

q 我也是刚看了一点书呀!顶下![em12]

137 楼

谢谢

138 楼

靠,是抄的!http://www.bc-cn.net/Article/kfyy/hb/jc/Index.html这上面都有!

139 楼

那些英语对我们记忆很有帮助

但是,我有些不太明白学汇编可以做些什么?
请赐教!

140 楼

很好的内容  慢慢学习

我来回复

您尚未登录,请登录后再回复。点此登录或注册