标签: memory-segmentation

如何使用 AT&T 汇编语法添加 `SS:` 或 `ES:`

如何在不添加 a或 的情况下添加a SS:orES:使用 AT&T 汇编语法?.byte 0x36.byte 0x26

IE。我如何能够在mov dword ptr ss:[esp+0x10], offset foo不使用以下内容的情况下从 Intel 语法转换为 AT&T:

.byte   0x36
movl    $foo, 0x10(%esp)
Run Code Online (Sandbox Code Playgroud)

我试过movl $foo, %ss:0x10(%esp)在没有警告的情况下组装,但是,通过二进制文件,仍然没有添加SS:

x86 assembly att memory-segmentation

2
推荐指数
1
解决办法
311
查看次数

Visual Studio 2010 - 数据段和堆栈内存相同

我发现一个常量的文字get放在程序的数据段中(来自SO)并且是只读的,因此行"s [0] ='a'"会导致错误,这实际上发生在我取消注释该行并运行.但是,当我查看MS VS中的内存窗口时,变量全部放在内存中.我很好奇他们(编译器)如何强制执行对's'的只读访问?

#include <iostream>

int main(void)
{
      char *s = "1023";
      char s_arr[] = "4237";
      char *d = "5067";
      char s_arr_1[] = "9999";
      char *e = "6789";
      printf("%c\n", s[0]);
//      s[0] = 'a'; This line would error out since s should point to data segment of the program
      printf("%s\n", s);
      system ("pause");
}

0x002E54F4  31 30 32 33 00 00 00 00 34 32 33 37 00 00 00 00  1023....4237....
0x002E5504  35 30 36 37 00 00 …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-memory memory-segmentation

2
推荐指数
1
解决办法
894
查看次数

为什么有两个重叠的数据段(例如在Linux内核中)?

在Linux内核以及在线的许多x86教程中,我看到人们建议使用两个代码段和两个数据段.我理解需要两个代码段,因为CPL需要与DPL完全匹配(对于不符合的段).

但是,这些教程中没有一个(也没有任何关于StackOverflow的相关问题),具体说明为什么我们需要两个数据段.这些工作与代码段不同,因为CPL = 0的进程可以访问DPL = 3的数据段.

如果我们在不同权限级别的进程之间切换,则具有两个数据段的缺点是必须重新加载DS,ES等寄存器.

所以我的具体问题是:鉴于我们使用的是平面内存模型,所有代码和段完全重叠,它的用途和内核数据段的用途是什么,而不仅仅是一个用户数据段?

x86 operating-system kernel linux-kernel memory-segmentation

2
推荐指数
1
解决办法
277
查看次数

DOS 在运行时插入段地址

我注意到我正在编写的一些代码中存在潜在的错误。

我认为,如果我使用mov ax, seg segment_name,该程序可能是不可移植的,并且只能在特定配置的一台机器上运行,因为加载位置可能因机器而异。

所以我决定在两台运行 DOS 的不同机器上反汇编一个只包含一条指令的程序,我发现问题神奇地解决了。

一号机上的调试输出:0C7A:014C B8BB0C MOV AX,0CBB

二号机器上的调试输出:06CA:014C B80B07 MOV AX,070B

十六进制转储程序后,我发现未更改的字节实际上是B84200.

手动将这些字节插入到程序中会导致mov ax, 0042

那么 PE 格式是否存储对这些指令的引用并在运行时更新它们?

dos relocation portable-executable memory-segmentation x86-16

2
推荐指数
1
解决办法
395
查看次数

386的“D位”中的“D”代表什么?

GDT 上的文章中, OSDev wiki 描述了用作 CS 描述符的 D 位的标志如下:

Sz:大小位。如果为0,则选择器定义 16 位保护模式。如果为1,则定义 32 位保护模式。您可以同时拥有 16 位和 32 位选择器。

另一个问题引用了 Intel 手册:代码段描述符中的 D 标志对 x86-64 指令有什么作用?它链接到Intel 64 和 IA-32 架构软件开发人员手册第 3 卷 [...]:系统编程指南中的“3.4.5 段描述符”部分 ,阅读:

D/B(默认操作大小/默认堆栈指针大小和/或上限)标志

根据段描述符是可执行代码段、向下扩展数据段还是堆栈段执行不同的功能。(对于 32 位代码和数据段,此标志应始终设置为 1,对于 16 位代码和数据段,应始终设置为 0。)

• 可执行代码段。该标志称为 D 标志,它表示段中指令引用的有效地址和操作数的默认长度。如果设置了标志,则假定为 32 位地址和 32 位或 8 位操作数;如果清楚,则假定为 16 位地址和 16 位或 8 位操作数。指令前缀 66H 可用于选择默认值以外的操作数大小,前缀 67H 可用于选择默认值以外的地址大小。

问题是,“D”代表什么?

x86 assembly terminology gdt memory-segmentation

2
推荐指数
1
解决办法
84
查看次数

为什么.COM 程序中只有一个段,既用于程序代码又用于堆栈?

我正在研究 .EXE 程序和 .COM 程序之间的区别。.EXE 对我来说是合乎逻辑的,堆栈位于相对于程序代码的另一个段中(实际上堆栈是强制的并用 .STACK 指示此限制),因此,当我去插入值时??堆栈(在 .EXE 中),使用与程序不同的段,我不会混淆这两者。

例子:

SP = 0400
SS = 3996 CS = 3995 IP = 0000
Run Code Online (Sandbox Code Playgroud)

栈的容量为1024 Byte(400h),指的是栈段3996h,不同于代码段3995h。所以我确信数据不会混淆。

我不明白的是什么时候我必须处理 .COM 程序;因为我很清楚他们只使用一个段,我发现自己遇到了类似的情况:

SP = FFEE
SS = 114A CS = 114A IP = 0100
Run Code Online (Sandbox Code Playgroud)

我有与代码段匹配的堆栈段。因此,如果我继续将值放入堆栈中,它们迟早会出现在我的代码中吗?

assembly dos memory-segmentation x86-16

2
推荐指数
1
解决办法
109
查看次数

x86 - 通过 RETF 从 32 位切换到 64 位

我正在研究一些反反汇编技术,并发现了以下片段:

push 0x33
call $+5
add  [esp+0x10+var_10], 5
retf
; next instruction here
Run Code Online (Sandbox Code Playgroud)

简而言之,这会立即跳转到 后面的指令RETF,但会弄乱 32 位反汇编程序。我仍然不清楚为什么会这样。

现在,我被告知RETF返回到 64 位段,因此在 32 位调试器上调试它会产生错误的反汇编。当在 64 位调试器(在我的例子中是 Windbg)上运行此代码片段时,它会产生正确的结果。

我的问题是:有什么特别的吗push 0x33?0x33 是某种特殊值吗?

x86 assembly x86-64 memory-segmentation

2
推荐指数
1
解决办法
107
查看次数

如何使用两个 16 位寄存器制作 20 位地址?

IAPX88 可以处理 1 兆字节内存(20 位寻址),现在我的问题是我们如何使用两个 16 位寄存器来制作 20 位地址。请举例说明。

assembly real-mode memory-segmentation x86-16

1
推荐指数
1
解决办法
1861
查看次数

RPL从哪里来?

我有点困惑,我从许多不同的网站上阅读,但我不清楚:

每个段寄存器都有可见部分和不可见部分。可见部分称为段选择器,并且有直接指令来加载段选择器。

请求者特权级别(RPL):该字段标识提供受保护的数据访问的特权级别。

好的,我知道我可以在汇编中使用指令,例如加载选择器,但我无法修改 RPL,对吧?它从何而来?CPU是如何选择的呢?谢谢

privileges x86 assembly osdev memory-segmentation

1
推荐指数
1
解决办法
553
查看次数

即使我确实为变量设置了初始值,数据段也没有被初始化

我已经编写了一个代码,它应该生成某种数字列表,但是即使我确实为它们分配了初始值,我的数据段变量也没有被初始化?

这是DS:0000我运行时的样子: ds:0000

这是我的代码,但数据段只保留垃圾值:

MODEL small
STACK 100h

DATA SEGMENT
    size1 dw 0000h
    arr dw 20 dup(0000h)
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA

sidra_rekursivit proc
    mov bp, sp
    xor ax, ax
    mov ax, [bp+2]
    ; tnai azira
    cmp ax, 1
    je azira
    
    ; tempo
    mov cx, ax ; save ax
    shr ax, 1
    jnc zugi ; if zugi

    
izugi:  ; else
    mov ax, cx
    ;multiply by 3
    shl ax, 1
    add ax, cx
    ;end multiply
    ; add 1 …
Run Code Online (Sandbox Code Playgroud)

assembly initialization dos memory-segmentation x86-16

1
推荐指数
1
解决办法
50
查看次数