汇编代码说明

发布于 2024-09-30 22:21:27 字数 402 浏览 3 评论 0原文

我已经开始学习组装了。我遇到过这些线。

;*************************************************;
; Second Stage Loader Entry Point
;************************************************;

main:
   cli  ; clear interrupts
   push cs ; Insure DS=CS
   pop ds

在第二行代码中,代码段被推送到堆栈(我认为是这样)。我在很多代码中都看到过。为什么我们应该这样做以及如何确保 DS =CS?第三行 DS 弹出堆栈(我认为是这样)。为什么这样做?它从堆栈中弹出意味着它之前被推入堆栈。没有相关的代码。有人可以向我解释这一切吗?提前致谢。

I have started to learn assembly. I came across these lines.

;*************************************************;
; Second Stage Loader Entry Point
;************************************************;

main:
   cli  ; clear interrupts
   push cs ; Insure DS=CS
   pop ds

Here on second line of code, the code segment is push to the stack(I think this). I have seen it in many codes. Why we should do this and how it ensures DS =CS? On third line DS is pop out of stack(I think this). Why it is done? It is pop out of stack means it was push to stack before. There is no code for that. Can anybody explain all this to me? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

弥繁 2024-10-07 22:21:28

csds 只是寄存器,非常类似于占位符/变量,更多信息有关寄存器的信息请阅读此处。在第二行中,您说 push cs 这意味着您将 cs 的内容放入堆栈中,并在下一行中pop 它返回到ds

所以刚刚发生的事情是将 cs 复制到 ds

push 是一条指令,内容为“将其放在堆栈顶部”

pop 是一条指令,表示“从堆栈中取出顶部值”

一旦执行pop,该值将不再存储在堆栈中。

cs and ds are just registers, pretty much like placeholders/variables, for more information about registers read here. On the second line you are saying push cs this means that you put the content of cs onto the stack and on the following line you pop it back into ds.

So what just happened was that you copied cs to ds.

push is an instruction that says "put this on top of the stack"

pop is an instruction that says "take the top value from the stack"

Once you do a pop the value is no longer stored on the stack.

温折酒 2024-10-07 22:21:28

有时可以使用 MOV 指令(例如 MOV ax,dx)来完成“将此寄存器压入堆栈,将堆栈弹出到此寄存器”。但某些寄存器到寄存器的 MOV 指令在指令集中不可用,并且 IIRC MOV ds,cs 也不可用。这可能就是将其放入内存(实际上是缓存)并读回的原因。

The 'push this register onto stack, pop stack to this register' can sometimes be done with MOV instructions, such as MOV ax,dx. But some register-to-register MOV instructions aren't available in the instruction set, and IIRC MOV ds,cs isn't available. That could be the reason for putting it in memory (well, cache, really) and reading it back.

衣神在巴黎 2024-10-07 22:21:28

就像评论中写的那样,push cs 然后 pop ds 确保 ds=cs?push cs 将 cs 的值放入栈顶,然后 pop ds 从栈中取出该值并将其存储在 ds 中。

Like in the comment written, push cs and then pop ds ensures that ds=cs?. push cs puts the value of cs on the top of the stack, and then pop ds removes the value from the stack and stores it in ds.

め可乐爱微笑 2024-10-07 22:21:28

通过将 CS 的值压入堆栈,然后将其弹出到 DS,可以确保 DS 与 CS 具有相同的值。

我已经有一段时间没有用汇编程序编程了,但我认为没有直接的方法可以从一个段寄存器移动到另一个段寄存器。

您可以将堆栈视为一堆数据。你把某样东西推到上面,它就会呆在那里,直到你把它从堆里弹出来。这样就可以使用堆栈来交换数据。但大多数时候你用它来保存数据,这样你就可以将寄存器用于其他目的并在以后恢复内容。

当您执行代码时会发生这种情况。

1) 初始情况

CS has value X
DS has value Y
Stack has ....

2) 压入 CS

CS has value X
DS has value Y
Stack has ...., X

3) 弹出 DS

CS has value X
DS has value X
Stack has ....

但什么是段寄存器。
过去,8086 有 16 位地址寄存器,但有 20 位地址空间。因此,他们使用段寄存器将段寄存器乘以 16,将两者组合成 20 位空间,并添加内存位置。为了节省空间,我们有近指针(没有段在段内跳转)和远指针(有段)。

随着 80286 保护模式的引入,段寄存器被重新用作段描述符。他们指出了一个内存位置,该位置提供了足够的信息来到达真实空间。但现在我们有了线性地址空间(虚拟映射到真实内存上)。

By pushing the value of CS to the stack, and popping it into DS, you ensure that DS has the same value as CS.

I haven't programmed in assembler for a while, but I thought there was no direct way to move from one segment register into another.

You can see the stack as a pile of data. You push something on top and it stays there until you pop it of\ the pile. In that way you can use the stack to exchange data. But most of the time you use it to save data so you can use the registers for other purposes and restore the content later.

This happens when you execute the code.

1) initial situation

CS has value X
DS has value Y
Stack has ....

2) push CS

CS has value X
DS has value Y
Stack has ...., X

3) pop DS

CS has value X
DS has value X
Stack has ....

But what are segment registers.
In the old days, 8086 had 16 bit address registers but a 20 bit addressspace. So they used the segment registers to combine both to a 20 bit space by multiplying the segment register by 16, and add the memory location. To save space, we had near pointers (without segment to jump within the segment) and far pointers (with segment).

With the introduction to 80286 protected mode, the segment registers were reused as segment descriptors. They pointed to a memory location that gave enough information to get to the real space. But now we have linear address spaces (virtually mapped on the real memory).

浪荡不羁 2024-10-07 22:21:27

确保这一点的不是 push cs,而是 push cs; pop ds; 组合就可以了。

第一条指令将 cs 的当前值复制到堆栈上,第二条指令将该值从堆栈中取出并将其放入 ds 寄存器中。


为了响应您对更多信息的请求,让我们从以下堆栈和寄存器开始:

stack=[1,2,3], cs=7, ds=6

After push cs,它将 cs 寄存器的值推送到堆栈上:

stack=[1,2,3,7], cs=7, ds=6

After < code>pop ds,从堆栈中弹出一个值并将其放入 ds 寄存器中:

stack=[1,2,3], cs=7, ds=7

基本上就是这样。


我不记得是否可以使用 mov 指令在段寄存器之间进行传输(我不认为是这样,但我可能是错的,这将需要推/弹出序列)。这个链接似乎证实了:没有mov 选项,将段寄存器作为源目标。

但即使是这样,汇编编码人员通常会选择更合适的指令,要么是为了速度,要么是为了紧凑的代码(或两者兼而有之),例如使用 xor ax, ax 而不是 mov ax, 0代码> 例如。

It's not the push cs that ensures this, it's the push cs; pop ds; combination that does.

The first instruction copies the current value of cs onto the stack, and the second pulls that value off the stack and puts it into the ds register.


In response to your request for more information, let's start with the following stack and registers:

stack=[1,2,3], cs=7, ds=6

After push cs, which pushes the value of the cs register onto the stack:

stack=[1,2,3,7], cs=7, ds=6

After pop ds, which pops a value off the stack and put it into the ds register:

stack=[1,2,3], cs=7, ds=7

And that's basically it.


I can't recall of the top of my head whether it was possible to transfer between segment registers with a mov instruction (I don't think it was, but I may be wrong, and this would necessitate the push/pop sequence). This link would seem to confirm that: there is no mov option with a segment register as both source and destination.

But even if it were, assembler coders often chose more suitable instructions, either for speed or compact code (or both), things like using xor ax, ax instead of mov ax, 0 for example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文