我需要帮助将值从寄存器移动到内存,但是每次运行代码时,我都会遇到段错误。目标是将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
答案 0 :(得分:2)
链接器不知道名为data:
或text:
的节,它们只是随机的自定义节名,您没有为其设置权限(读取/写入/执行)。 (请在标签后使用:
,而不要在部分名称后使用
您要section .data
和section .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下单步执行直到尝试将其存储回内存时才进行段错误处理,并且由于 被映射为只读状态而出错。 >
是的,节名末尾的:
实际上出现在目标文件中。