标签: memory-segmentation

汇编程序如何计算符号地址的段和偏移量?

我已经学习了编译器和汇编语言,所以我想编写自己的汇编程序作为练习。但我有一些问题;

如何计算@DATA 或 OFFSET/ADDR VarA 等段的地址?

以一个简单的汇编程序为例:

    .model small
    .stack 1024
    .data
          msg db 128 dup('A')
    .code
    start:
        mov ax,@data
        mov ax,ds
        mov dx, offset msg
                           ; DS:DX points at msg
        mov ah,4ch
        int 21h            ; exit program without using msg
    end
Run Code Online (Sandbox Code Playgroud)

那么汇编器是如何计算段的段地址的@data呢?

它如何知道将什么放入立即数mov dx, offset msg

compiler-construction assembly masm memory-segmentation x86-16

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

GDB查找命令错误"警告:无法在y处访问x字节的目标内存,停止搜索"

我正在尝试使用gdb在KMines中查找当前的标志计数.我知道我应该首先寻找内存映射以避免不存在的内存位置.所以我运行info proc mappings命令来查看内存段.我0xd27000-0x168b000从结果中获取了一个随机内存gap()并执行了如下命令:find 0x00d27000, 0x0168b000, 10

但我得到了warning: Unable to access 1458 bytes of target memory at 0x168aa4f, halting search.错误.虽然地址0x168aa4f介于0xd27000和0x168b000之间,但gdb表示它无法访问它.为什么会这样?我该怎么做才能避免这种情况?或者有没有办法忽略未映射/不可访问的内存位置?

编辑:我试图将地址0x168aa4f的值设置为1并且它可以工作,因此gdb实际上可以访问该地址,但在与find命令一起使用时会出错.但为什么?

debugging gdb find memory-segmentation

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

底层段寄存器的线程本地实际使用

我阅读了许多文章和 S/O 答案说(在 linux x86_64 上)FS(或某些变体中的 GS)引用了一个特定于线程的页表条目,然后它给出了一个指向可共享的实际数据的指针数组数据。当线程被交换时,所有的寄存器都被切换,因此线程基页会发生变化。线程变量通过名称访问,只需要 1 个额外的指针跃点,并且引用的值可以共享给其他线程。一切都好,说得通。

事实上,如果你查看__errno_location(void)背后的函数的代码errno,你会发现类似的东西(这是来自 musl,但 gnu 并没有太大的不同):

static inline struct pthread *__pthread_self()
{
    struct pthread *self;
    __asm__ __volatile__ ("mov %%fs:0,%0" : "=r" (self) );
    return self;
}
Run Code Online (Sandbox Code Playgroud)

来自 glibc:

=> 0x7ffff6efb4c0 <__errno_location>:   endbr64
   0x7ffff6efb4c4 <__errno_location+4>: mov    0x6add(%rip),%rax        # 0x7ffff6f01fa8
   0x7ffff6efb4cb <__errno_location+11>:        add    %fs:0x0,%rax
   0x7ffff6efb4d4 <__errno_location+20>:        retq
Run Code Online (Sandbox Code Playgroud)

所以我的期望是 FS 的实际值会因每个线程而改变。例如,在调试器下, gdb: info regor p $fs,我会看到 FS 的值在不同的线程中是不同的,但没有: ds, es, fs, gs 一直都为零。

在我自己的代码中,我写了类似下面的内容并得到相同的结果 - FS 没有改变,但 TLV “有效”:

struct …
Run Code Online (Sandbox Code Playgroud)

c++ linux x86-64 thread-local-storage memory-segmentation

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

使用GDB读取MSR

在使用GDB调试程序时,有什么方法可以读取特定于x86-64模型的寄存器,尤其是IA32_FS_BASE和IA32_GS_BASE?

使用像Intel的Pintool这样的动态工具包的解决方案是不太可取的,但是同样可以理解。

x86 gdb x86-64 msr memory-segmentation

4
推荐指数
3
解决办法
845
查看次数

在 x64 中完全不使用分段吗?

在 x86 中,当您想要访问内存地址时,您将指定一个地址,该地址将通过两个阶段转换为内存地址:分段分页

在此处输入图片说明

但是在 x64 中也使用分段吗?(我认为它没有被使用,但我不确定它是不是在所有情况下都使用,或者在某些情况下使用它)。

x86 operating-system x86-64 memory-segmentation

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

如何在 Visual Studio 调试器中查看段偏移内存地址?

我正在从反汇编中调试一些代码(没有可用的源代码),并且有许多指令通过ds段寄存器访问数据,例如这样的:

66 3B 05 8A B1 43 00 cmp         ax,word ptr ds:[43B18Ah]
Run Code Online (Sandbox Code Playgroud)

你如何让 Visual Studio 调试器告诉你ds段寄存器的偏移量,以便我可以检查它所指的内存?Watch 窗口似乎不接受像ds:[0x43B18A]或变体这样的表达式;它会告诉我那ds是 0,但这并没有告诉我段 0 的偏移量是多少。

是否有一些特殊的语法,或者这是 VS 无法做到的?使用其他调试器(例如 WinDbg 或 ntsd)会更好吗?

debugging x86 disassembly visual-studio memory-segmentation

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

默认使用哪个段寄存器?

我正在学习英特尔手册中的计算机体系结构。我的理解是,我们给出的指令是由段选择器和偏移量组成的逻辑地址。它基本上是CS register<<4 + offset。在Segment Selector映射到GDTLDT为在给定TI的段选择的位。GDT 由Segment Descriptorshave BASE, LIMITand组成,RPL输出是基地址。这个base address+offset提供了logical address.

什么是决定段寄存器(其中的规则SSDS等),适用于不同的存储操作?例如,什么决定了哪个段用于mov eax, [edi]

x86 assembly memory-segmentation

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

操作系统和汇编:什么阻止用户模式将选择器设置为任意值?

我知道操作系统通过使用分段和特权级别来限制对内核代码和数据的访问。然而,用户可以更改段寄存器的值,如果以下代码执行成功,我们似乎可以访问内核数据:

mov eax, 0x10 
mov es, ax   #point selector to the item 2 in GDT with RPL 0, which is the data segment
les bx, [0]
Run Code Online (Sandbox Code Playgroud)

所以我想知道阻止此代码成功执行的机制是什么?

x86 assembly operating-system gdt memory-segmentation

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

为什么“分段错误”在 C 中仍然存在

操作系统中的分段是一个与时间本身一样古老的概念。至少根据我的教授的说法,大多数现代操作系统已经放弃了分段的概念,现在主要依靠分页来实现内存保护,从而防止每个进程访问除自己的内存之外的任何其他内存。那么我们如何在 C 中仍然遇到“分段错误”。在现代操作系统中,我们是否仍然将分段作为一个抽象概念?

c operating-system x86-64 segmentation-fault memory-segmentation

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

为什么 mov %ax, %ds 汇编+反汇编为 mov %eax,%ds,与原来不一致?

测试.S

.text
.global _start
    _start:
        xor %ax, %ax
        mov %ax, %ds
        mov %ax, %ss
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
Run Code Online (Sandbox Code Playgroud)

我通过这样做得到了反汇编代码文件

$ x86_64-elf-gcc -g -c -O0 -m32 -fno-pie -fno-stack-protector -fno-asynchronous-unwind-tables .\test.S
$ x86_64-elf-ld .\test.o -m elf_i386  -Ttext=0x7c00 -o test.elf
$ x86_64-elf-objdump -x -d -S -m i386 ./test.elf > test_dis.txt
Run Code Online (Sandbox Code Playgroud)

测试_dis.txt


./test.elf:     file format elf32-i386
./test.elf
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00007c00

Program Header:
    LOAD off    0x00000000 vaddr 0x00007000 paddr 0x00007000 align 2**12
         filesz …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gnu-assembler objdump memory-segmentation

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