【发布时间】:2020-12-27 13:24:27
【问题描述】:
我目前正在学习汇编。 我想编写一个程序,它以三个相互指向的变量结束:
0x804a000: 0x804a001 ; 0 -> 1
0x804a001: 0x804a002 ; 1 -> 2
0x804a002: 0x804a000 ; 2 -> 0
Accordingtosomeotherposts,我可以检索(例如mov):
- 变量
x的内容使用[x] - 变量地址
x使用x
到目前为止,这是我想出的:
section .bss
head resd 3 ; reserve three dwords
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx ; counter = 0
mov eax, head ; move the address of head into eax: eax -> 0
mov ebx, eax ; move the address of head from eax into ebx: ebx -> 0
add ebx, 2 ; ebx -> 2
mov [ebx], eax ; move the value of eax ( = the address of 0 ) into the address in ebx ( = the address of 2)
loop: ; first run second run
inc ecx ; eax -> 0 eax -> 1
mov ebx, eax ; ebx -> 0 ebx -> 1
add eax, 1 ; eax -> 1 eax -> 2
mov [ebx], eax ; 0 -> 1 1 -> 2
cmp ecx, 2 ; ecx = 1 < 2 ecx = 2 == 2
jl loop
mov eax, head ; eax points to the first element
mov eax,1 ; system call number (sys_exit)
int 0x80 ; call kernel
这应该基本上
0.保留三个dword,第一个在head中的地址
- 将0的地址加载到
eax,将2的地址加载到ebx -
mov [ebx], eax将0的地址写入2(2 -> 0) - 对字段 0 和 1 重复相同的操作:
0 -> 1、1 -> 2 - 将head的地址存入eax
现在我使用
组装和运行整个事情nasm -f elf -g -F dwarf test.asm
ld -m elf_i386 -o test.out test.o
但是,0 和 2 中的值都是错误的,我可以使用 gdb 进行检查:
gdb test.out
(gdb) b 27 // break after mov eax, head
(gdb) r
(gdb) i r eax
eax 0x804a000 134520832 // eax points to head
(gdb) print *134520832
$1 = 77595137 // cell 0 does not point to cell 1
(gdb) print *134520833
$2 = 134520834 // cell 1 does point to cell 2
(gdb) print *134520834
$3 = 134743200 // cell 2 does not point to cell 1
这些错误值从何而来?
这可能是因为我尝试将整个 32 位 eax 写入 16 位双字?
我尝试将这些行更改为mov [ebx], ax,但结果相同。
我能想到的另一个原因是内存地址大于dword,所以我尝试使用qwords,但结果又出现了错误。
我还尝试使用lea assembly instruction 中建议的lea 指令,结果相同。
有人可以帮我解决这个问题吗?提前致谢
【问题讨论】:
标签: assembly x86 nasm memory-address