将寄存器值移至段数据中的存储器变量

时间:2019-04-15 06:07:34

标签: assembly x86 nasm

我需要帮助将值从寄存器移动到内存,但是每次运行代码时,我都会遇到段错误。目标是将M分配给J + K-1。

section data:
    M dw 0
    J dw 3
    K dw 4

section text:

    global _start

    ; Show how this statement M= J+K -1 could be translated into assembly code using 8086 instruction set.
    ; Assume M, J and K are memory variables. In 8086 assume 16-bit, we can use MOV
    ; instruction to copy the variable into register ex: MOV AX, J.

    _start:
        mov bx, [K] ; move K into bx
        sub bx, 1 ; subtract 1 from bx
        mov ax, [J] ; move J into ax
        add ax, bx ; add J + (K - 1)
        mov [M], ax ; move ax value into M. This is where the seg fault occurs.

        mov rax, 60
        mov rdi, 0
        syscall

1 个答案:

答案 0 :(得分:2)

链接器不知道名为data:text:的节,它们只是随机的自定义节名,您没有为其设置权限(读取/写入/执行)。 (请在标签后使用:,而不要在部分名称后使用

您要section .datasection .text

(此外,我建议使用default rel,因为您希望NASM对[K]之类的地址使用相对RIP寻址。)


在Arch Linux桌面上使用nasm -felf64 foo.asm && ld -o foo foo.o构建静态可执行文件后,

$ readelf -a foo
...
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
                 0x0000000000000031 0x0000000000000031  R      0x1000

 Section to Segment mapping:
  Segment Sections...
   00     data: text: 

...

因此,我们可以看到text:data:部分都链接了一个只读的不可执行程序段,因此_start的第一条指令的代码获取将出错。或至少您会期望这样做,但是在GDB下单步执行直到尝试将其存储回内存时才进行段错误处理,并且由于 被映射为只读状态而出错。 >

是的,节名末尾的:实际上出现在目标文件中。