assembly - 在程序集中初始化变量
问题描述
我正在 i386 Assembly 中编写 Forth 解释器。一些数据需要在开始时初始化,然后作为错误恢复过程的一部分在稍后重新初始化。
我遵循了https://sourceware.org/binutils/docs/ld/Scripts.html中的链接器脚本指南,但它似乎不像描述的那样工作。具体来说,第 3.6.8.2 节讨论了使用 AT 功能以及需要一些初始化代码来复制初始化数据。但是,当我运行我的程序时,数据似乎已经初始化(没有副本),所以我不知道如何重新初始化它。
我已经用以下内容重现了这个问题......
我有一个汇编程序my.S
:
.text
_start:
cld
mov $_etext,%esi
mov $_data,%edi
mov $_edata,%ecx
sub %edi,%ecx
rep movsb
mov (the_answer),%eax
mov $1,%ebx
int $0x80
.data
the_answer:
.long 42
在my.x
我有我的链接器脚本:
SECTIONS
{
.text 0x08048000 : { *(.text) _etext = . ; }
.mdata 0x80000000 :
AT ( ADDR (.text) + SIZEOF (.text) )
{ _data = . ; *(.data); _edata = . ; }
.bss :
{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}
}
构建镜像的命令是:
gcc -g -o my.o my.S -c -m32 -Wa,-agnlsc > my.lst
ld -m elf_i386 -T my.x -Map=my.map my.o -o my
my.map 文件显示
.mdata 0x0000000080000000 0x4 load address 0x0000000008048020
也就是说,正如预期的那样,“运行时”VMA 地址是 0x80000000,而“加载时间”LMA 是 0x08048020。根据其他地方的描述,我希望在程序开始时执行一些代码来将数据从 LMA 地址复制到 VMA 地址(如 中所示my.S
)。
然后我运行gdb my
并执行:
(gdb) break _start
...
(gdb) run
...
(gdb) x/w 0x8048020
0x8048020: 0
(gdb) x/w 0x80000000
0x80000000: 42
所以在不执行复制代码的情况下,初始化数据出现在VMA地址,而不是手册中描述的LMA地址。这无关紧要,只是我需要能够在以后重新初始化数据。
解决方案
推荐阅读
- steam - 如何获取给定 Steam 应用程序的所有所有者?
- typescript - TypeScript 错误:事件处理程序的“对象”类型上不存在属性“目标”
- ruby - Ruby rspec将带有字符串的模拟哈希转换为带有符号的哈希
- sql - SQL Server 将三个不同的列连接成逗号分隔且没有重复值
- html - 如何解决用于在表中搜索的异步管道中的错误?
- python - logits 和 labels 必须是可广播的,labels 和 logits 维度不匹配
- regex - 如何使用正则表达式提取信息
- php - 在 PHP 中的 mySQL Server 上执行存储过程时如何获取 lastInsertID?
- javascript - 如何在反应中没有eval()的情况下从一个输入计算值
- javascript - 不兼容的 Bable 版本 React