首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法理解寄存器和变量之间的程序集移动指令

无法理解寄存器和变量之间的程序集移动指令
EN

Stack Overflow用户
提问于 2017-11-05 15:15:24
回答 2查看 3.7K关注 0票数 3

我在linux 64位上使用NASM汇编程序。有一些变量和寄存器我无法理解。我创建了一个名为“msg”的变量:

代码语言:javascript
运行
复制
 msg db "hello, world"  

现在,当我想写到标准输出时,我将msg移动到rsi寄存器,但是我不理解mov指令的位.rsi寄存器由64位组成,而msg变量有12个符号,每个符号8位,这意味着msg变量的大小为12 * 8位,明显大于64位。

那么,如何才能做出这样的指示:

mov rsi, msg,而不溢出分配给rsi的内存。

或者rsi寄存器是否包含字符串的第一个符号的存储位置,并且在写入1符号之后,它更改为下一个符号的内存位置?

对不起,如果我写的都是胡说八道,我是刚开始组装的,我只是一时搞不懂。

EN

回答 2

Stack Overflow用户

发布于 2017-11-05 16:09:45

在NASM语法中(与MASM语法不同),mov rsi, symbol将符号的地址放入RSI中。(使用64位绝对即时,效率不高;使用相对于RIP的LEA或mov esi, symbol代替。How to load address of function or label into register in GNU Assembler)

mov rsi, [symbol]将从symbol开始加载8个字节。在编写这样的指令时,您应该选择一个有用的位置来加载8个字节。

代码语言:javascript
运行
复制
mov   rsi,  msg           ; rsi  = address of msg.  Use lea rsi, [rel msg] instead
movzx eax, byte [rsi+1]   ; rax  = 'e' (upper 7 bytes zeroed)
mov   edx, [msg+6]        ; rdx  = ' wor' (upper 4 bytes zeroed)

请注意,您可以使用mov esi, msg,因为符号地址总是适合32位(在默认的“小”代码模型中,所有静态代码/数据都位于低2GB的虚拟地址空间中)。NASM使用组装时间常数(如mov rax, 1)为您进行了这种优化,但可能不能用链接时间常数进行优化。Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?

在写完一个符号之后,它会改变到下一个符号的内存位置?

不,如果你想那样的话,你必须要inc rsi。没有魔法。指针只是你和其他整数一样操作的整数,字符串只是内存中的字节。

访问寄存器不会神奇地修改它们。

有像lodsbpop这样的指令从内存加载指针和增量指针(rsirsp ),但是x86没有任何前置/后增量/递减寻址模式,所以即使您想使用mov,也无法获得这种行为。使用add/subinc/dec

票数 7
EN

Stack Overflow用户

发布于 2017-11-05 15:41:35

免责声明:我不熟悉您正在处理的程序集的风格,因此下面的内容更一般。特别的味道可能比我习惯的有更多的特色。通常,程序集处理的是单字节/字实体,其大小取决于处理器。我在8位和16位处理器上做了很多工作,所以这就是我的答案。

关于程序集的通用声明:程序集就像一种高级语言,但您必须处理更多的细节。因此,如果您习惯了C中的某些操作,您可以从那里开始,然后进一步分解操作。

例如,如果您声明了要添加的两个变量,这在C中非常容易:

代码语言:javascript
运行
复制
x = a + b;

在组装过程中,您必须进一步分解:

代码语言:javascript
运行
复制
mov R1, a  * get value from a into register R1
mov R2, b  * get value from b into register R2
add R1,R2  * perform the addition (typically goes into a particular location I'll call it the accumulator
mov x, acc * store the result of the addition from the accumulator into x

根据程序集的风格和处理器的不同,您可能可以直接引用加法指令中的变量,但正如我所说的,我必须查看您正在使用的特定版本。

评论您的特定问题:,如果您有一个字符串,那么您将不得不使用某种循环单独移动每个字符。我会设置一个寄存器来包含您的字符串的起始地址,然后在移动每个字符之后增加该寄存器。它的作用就像C中的指针一样,您将需要对字符串的终止有某种指示,或者另一个指示字符串大小的值,这样您就知道什么时候停止。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47123137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档