首页
社区
课程
招聘
[求助]我学汇编碰到的一些问题(新手级)
发表于: 2009-4-26 13:58 10989

[求助]我学汇编碰到的一些问题(新手级)

2009-4-26 13:58
10989

自学汇编碰到许多问题,有的已经解决,有的还没解决,都写在这里。
自己寻找问题的答案时也问过许多人,走过不少弯路,希望这篇文章能为有同样问题的朋友省下许多弯路。

1. push指令是什么意思?
答:压栈(看不懂吧。。呵,往后看。)。相信做过破解的人都会注意到,程序里push指令是最常出现的指令之一,那么这个指令到底是什么意思呢?问了高手们,都说是压栈。我们知道栈只是一种数据结构,那么汇编里的栈和我们数据结构的栈是不是一回事呢?事实上,不是的!汇编里的push是将push后面的数据压入系统栈。所谓系统栈,通常是开辟在内存最低层的连续数据空间,用于什么我就不知道了。但是这块数据空间是具有栈的特性的,也就是所谓的先进后出。所以这块空间叫做系统栈。push压栈操作,就是把数据压到系统栈里。

ps:这个问题的回答是我问了许多人之后的心得。但是我发给我同学看(他们有汇编课,我则是自学的,所以经常请教他),他告诉我,那个系统栈应该是堆栈段,而且不是系统分配的,而是自己装入的。我就有点糊涂了。

回答:
by2楼 mik

对于 push 指令,认为简单就是简单,认为复杂就是复杂

下面看看从低往深的理解:

第1层:就是入栈

第2层:怎样入栈?用C代表就是:esp--; *esp = XXX;

第3层:esp-- 是多少?
  答案:一般来说:在实模式下是 esp 减 2,在保护模式下 esp 减 4,在 64 bit 模式下 rsp 减 8。

第4层:为什么实模下减 2,保护模式下减 4,64 bit 模式下减 8 ?
  答案:esp(stack pointer)减多少,取决于 SS.B。
  SS.B 是什么?SS.B 就是 SS 寄存器内的 B 属性,这个 B 属性就是:data segment default operand size(数据段缺省的操作数大小),SS 寄存器所装载的 segment descriptor 这时表示为 stack segment descriptor,B 属性用来表示:缺省的 stack 的操作数大小。
  即:B = 1 时,它的栈操作数是 32 位,B = 0,它的栈操作数是 16 位。

  在实模式下,SS.B 一定是 0,表示实模式下栈的操作数是 16,所以,sp 减 2。
  在保护模式下,SS.B 总是被置为 1,表示保护模式下操作数是 32 位,所以,esp 减 4。
  在 64 bit 模式下,SS.B 是无效的,x64 定义栈操作数强制为 64 位。

第 5 层:可以更改栈操作数大小吗?
  答案:可以。
  在实模式下,几乎不能更改栈操作数大小,但还是有办法的,这里就不说了。
  在保护模式下,若定义的 B = 0 则为16 位,但所有的 OS 都不会这么做。所有 OS 栈的缺省操作数都是 32 位。
  但是,可以 32 位的栈上强制压入 16 位的值。这样造成栈边界不对齐。产生性能问题。
  在 64 位模式下,不能改变,所有的栈操作数都是 64 位。

第6层:push 压入的数据是多大?
  答案:缺省情况下,就是上面所说的栈操作数大小。
  但是,在强制情况下,16 位栈可以压入 32 位值,32位栈可以压入16位。64位栈只能固定压入64位值。

第7层:压入后栈指针,指向哪?
  答案:就是栈顶,ESP 指向栈顶。

第8层:往哪个栈压栈呢?
  答案:就是往当前的栈压入栈。

第9层:什么是当前的栈?
  答案:SS:SP、SS:ESP 和 SS:RSP 就是代表当前的栈。
  当 SS:ESP 指向内核栈时,当前的栈就是内核栈。当 SS:ESP 指向用户栈时,当前的栈就是用户栈。

第10层:什么时候指向用户栈?什么时候指向内核栈?
  答案:当代码转入内核,或者说:代码陷入内核时。SS:ESP 会切换到内核栈。一般的应用层上都使用用户栈。

第11层:能使用DS访问栈吗?
  答案:看情况,在平垣的内存模式下,可以使用DS该问栈,也就是,数据段来指引栈段。现在绝大多数OS 都是平垣的内存管理模式下,所以,绝大多数情况下,可以用DS段访问SS 段

-----------------------------------------------------------
  上面的11层中,你理解到哪一层呀?

  一般的人都是理解到 第 3 层而已。。。

回答二: by3楼 hzfc
SS 堆栈段  esp是堆栈寄存器,始终指向栈顶
Push把值压入堆栈 esp=esp-4  入栈元素存入esp
Pop把值弹出堆栈  把esp中存储值给出栈元素 esp=esp+4

2. 据说伪指令是不进行实际操作的。那么我们可以不写吗?为什么?

答:by4楼 要学汇编
伪指令要写,记得好象看过伪指令是在编译器这一层来支持的,源代码中的伪指令编译时都被编译器实现了.

3. fstsw指令是什么意思?~ 什么是浮点运算?
by 16楼 cmdxhz

FSTSW:
FPU储存狀态暂存器值至AX(这个指令的功用是用来把状态字组取出并存入记忆体变数里,而这个记忆体变数必须是 16 位元的记忆体变数)

FPU 的暂存器可分为五类,堆叠暂存器 (register stack)、状态字组 (status word)、控制字组 (control word)、标籤字组 (tag word)、例外指标 (exception pointer)。虽然看起来很複杂,但是最重要且最常用的是堆叠暂存器。

FPU 共有八个堆叠暂存器,分别是 ST、ST(1)、ST(2)、ST(3)……ST(7),这八个暂存器每一个都是 80 位元,用来存放运算时所需要的资料,这和以前我们所说的堆叠所存的资料不太相同,但是操作方式却是一样的。FPU 许多运算都是先把数值推入堆叠顶端的 ST 暂存器,再对 ST 暂存器作运算
使用



4. 看汇编的书,似乎寄存器就是eax,ebx那些常用的加上flag寄存器。原来后面那些st0,st1...也是寄存器。但是书上都没提到过(我看的80x86汇编语言)。这样很误导我们这样的初学者。能不能详绍一下,cpu里的寄存器数量,功能(我猜每个CPU都是不同的,但是大概介绍下吧^ ^);

我会尽量快地更新这篇文章,整理回答,并提出新的问题。
另外各位有什么问题也可以提出来,我会整理到一楼来的^ ^
希望踊跃拍砖,多多指出不足指出。
万分感谢看贴和回帖的各位朋友。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (25)
雪    币: 723
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
2
对于 push 指令,认为简单就是简单,认为复杂就是复杂

下面看看从低往深的理解:

第1层:就是入栈

第2层:怎样入栈?用C代表就是:esp--; *esp = XXX;

第3层:esp-- 是多少?
  答案:一般来说:在实模式下是 esp 减 2,在保护模式下 esp 减 4,在 64 bit 模式下 rsp 减 8。

第4层:为什么实模下减 2,保护模式下减 4,64 bit 模式下减 8 ?
  答案:esp(stack pointer)减多少,取决于 SS.B。
  SS.B 是什么?SS.B 就是 SS 寄存器内的 B 属性,这个 B 属性就是:data segment default operand size(数据段缺省的操作数大小),SS 寄存器所装载的 segment descriptor 这时表示为 stack segment descriptor,B 属性用来表示:缺省的 stack 的操作数大小。
  即:B = 1 时,它的栈操作数是 32 位,B = 0,它的栈操作数是 16 位。

  在实模式下,SS.B 一定是 0,表示实模式下栈的操作数是 16,所以,sp 减 2。
  在保护模式下,SS.B 总是被置为 1,表示保护模式下操作数是 32 位,所以,esp 减 4。
  在 64 bit 模式下,SS.B 是无效的,x64 定义栈操作数强制为 64 位。

第 5 层:可以更改栈操作数大小吗?
  答案:可以。
  在实模式下,几乎不能更改栈操作数大小,但还是有办法的,这里就不说了。
  在保护模式下,若定义的 B = 0 则为16 位,但所有的 OS 都不会这么做。所有 OS 栈的缺省操作数都是 32 位。
  但是,可以 32 位的栈上强制压入 16 位的值。这样造成栈边界不对齐。产生性能问题。
  在 64 位模式下,不能改变,所有的栈操作数都是 64 位。

第6层:push 压入的数据是多大?
  答案:缺省情况下,就是上面所说的栈操作数大小。
  但是,在强制情况下,16 位栈可以压入 32 位值,32位栈可以压入16位。64位栈只能固定压入64位值。

第7层:压入后栈指针,指向哪?
  答案:就是栈顶,ESP 指向栈顶。

第8层:往哪个栈压栈呢?
  答案:就是往当前的栈压入栈。

第9层:什么是当前的栈?
  答案:SS:SP、SS:ESP 和 SS:RSP 就是代表当前的栈。
  当 SS:ESP 指向内核栈时,当前的栈就是内核栈。当 SS:ESP 指向用户栈时,当前的栈就是用户栈。

第10层:什么时候指向用户栈?什么时候指向内核栈?
  答案:当代码转入内核,或者说:代码陷入内核时。SS:ESP 会切换到内核栈。一般的应用层上都使用用户栈。

第11层:能使用DS访问栈吗?
  答案:看情况,在平垣的内存模式下,可以使用DS该问栈,也就是,数据段来指引栈段。现在绝大多数OS 都是平垣的内存管理模式下,所以,绝大多数情况下,可以用DS段访问SS 段

-----------------------------------------------------------
  上面的11层中,你理解到哪一层呀?

  一般的人都是理解到 第 3 层而已。。。
2009-4-26 15:50
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
1.SS 堆栈段  esp是堆栈寄存器,始终指向栈顶
Push把值压入堆栈 esp=esp-4  入栈元素存入esp
Pop把值弹出堆栈  把esp中存储值给出栈元素 esp=esp+4
2.伪指令需要写
2009-4-26 19:52
0
雪    币: 350
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看看是不是现金: 200 Kx

伪指令要写,记得好象看过伪指令是在编译器这一层来支持的,源代码中的伪指令编译时都被编译器实现了.
2009-4-26 20:53
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
谢谢楼上的回答。另外再问一下
1. esp指令所指的堆栈段若在程序中没有装入,系统是怎么分配的?
2. fstsw指令是什么意思?~
2009-4-29 15:15
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
正在看王爽的汇编语言,推荐去看看吧,其中第三章有push、pop的讲解感觉让我这个菜鸟明白了不少
2009-4-29 16:02
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
7
貌似push指令没有这么恐怖吧,而且所划得层次感觉有些不实:比如说,有些人明白了第七层却不知第四层是为何?却是为何!
2009-4-29 16:04
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
支持MIK,经典...
2009-4-29 16:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
呵呵,写得真详细。
2009-4-29 21:46
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
路过学习了。楼主的精神值得学习呀
2009-4-29 23:01
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
买一本书,下50级的视频教程 1个月就可以学会了,然后就都能看懂一般的知识了。
2009-4-29 23:48
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
伪指令要写,push我也不是很理解..
2009-4-30 15:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
啊,2楼的朋友写得真详细
2009-4-30 15:58
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
感谢大家的发言 感谢十楼夸奖
2009-4-30 20:14
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
恩。很详细。收下慢慢看
2009-5-2 19:39
0
雪    币: 1753
活跃值: (885)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
16
回楼主后面的问题~!~!:

FSTSW:
FPU储存狀态暂存器值至AX(这个指令的功用是用来把状态字组取出并存入记忆体变数里,而这个记忆体变数必须是 16 位元的记忆体变数)

FPU 的暂存器可分为五类,堆叠暂存器 (register stack)、状态字组 (status word)、控制字组 (control word)、标籤字组 (tag word)、例外指标 (exception pointer)。虽然看起来很複杂,但是最重要且最常用的是堆叠暂存器。

FPU 共有八个堆叠暂存器,分别是 ST、ST(1)、ST(2)、ST(3)……ST(7),这八个暂存器每一个都是 80 位元,用来存放运算时所需要的资料,这和以前我们所说的堆叠所存的资料不太相同,但是操作方式却是一样的。FPU 许多运算都是先把数值推入堆叠顶端的 ST 暂存器,再对 ST 暂存器作运算
使用

在OD的寄存器地方就可以看到这8个堆叠暂存器 如图:
上传的附件:
2009-5-3 04:02
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
17
感谢cmdxhz的回答
2009-5-3 11:10
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
如果你要跑航线,就驾船按航线跑,终点码头是你的目标。
如果你要探寻大海的奥秘,你就驾船满大海探寻。
如果你要浏览大海风光,你就满大海跑船。。。
2009-5-3 12:14
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
19
- -啥?~
2009-5-4 10:37
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
辛苦啊 lZ.
2009-8-4 11:04
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
好有哲理 没怎么理解明白 我的理解:
如果我是想学破解软件,那就拿汇编当船用,达到破解的目的
如果我是想学汇编,就要把他学好
如果只是想了解下,就粗略的看一遍吧

    理解不对,不要BS我
2009-8-4 22:03
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
push就是压栈啊
2009-9-17 15:35
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
楼主的研究精神值得学习~~
2009-9-20 16:33
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
狂赞2楼,真详细!
2009-9-21 21:27
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
学习一下进来
2009-10-20 00:12
0
游客
登录 | 注册 方可回帖
返回
//