Перемещение значений регистра в переменные памяти в разделе данных - PullRequest
0 голосов
/ 15 апреля 2019

Мне нужна помощь в перемещении значения из регистра в память, но каждый раз, когда я запускаю свой код, я получаю ошибку сегмента. Цель состоит в том, чтобы присвоить 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 Ответ

2 голосов
/ 15 апреля 2019

Компоновщик не знает о разделах, называемых data: или text:, это просто произвольные имена пользовательских разделов, и вы не задали для них права (чтение / запись / выполнение). (Используйте : после меток, а не имен разделов)

Вы хотите section .data и section .text

(Кроме того, я бы порекомендовал default rel, поскольку вы хотите, чтобы NASM использовал относительную RIP-адресацию для таких адресов, как [K].)


После создания статического исполняемого файла с nasm -felf64 foo.asm && ld -o foo foo.o на моем рабочем столе Arch Linux,

$ 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 не привело к сбою до тех пор, пока он не попытался сохранить данные в памяти, и это привело к ошибке, поскольку является отображенным только для чтения.

И да, : в конце имен разделов действительно появился в объектном файле.

...