assembly - 将寄存器值移动到节数据中的内存变量
问题描述
我需要帮助将值从寄存器移动到内存,但每次运行代码时都会出现段错误。目标是将 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
解决方案
链接器不知道称为data:
or的部分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 下单步执行它直到它尝试存储回内存时才出现段错误,并且由于它是只读映射的,所以出现了错误。
是的,:
部分名称末尾的 确实确实出现在目标文件中。
推荐阅读
- c# - 创建 CSV 文件会生成损坏的数据
- swift - 将数据从firebase加载到标签?
- c# - 为什么 Azure 函数会发送永无止境的 HTTP 请求?
- excel - 部分保护工作簿(并允许宏输入受保护的单元格)
- google-cloud-platform - 谷歌云平台 LAMP 设置 Laravel 5.4
- python - Python 请求模块挂在套接字连接上,但 cURL 有效
- polymer - Polymer init 在“正在运行的生成器”上停止(polymer-cli 1.8.0,Polymer 3.0)
- python - 我如何计算用户输入输入所需的时间?
- sql-server - 如何在循环中使用联合我试图联合结果谢谢
- ruby-on-rails - Rails:ActiveRecord 查询所有关联是/不是值