Assembly [var]和var之间的程序集差异
我正在学习汇编程序,现在我对Assembly [var]和var之间的程序集差异,assembly,x86,nasm,Assembly,X86,Nasm,我正在学习汇编程序,现在我对[variable]和variable之间的区别一无所知。正如教程所说,两者都是指针,那么这有什么意义呢?为什么我必须在[]之前使用类型标识符? 我的汇编程序:nasm x86\u 64在Linux-->Ubuntu上运行在x86英特尔语法中[expression]表示地址expression处的内存内容 (在MASM中,当表达式是数值文字或eq常量且无寄存器时除外) 表达式不带括号取决于您使用的汇编程序 NASM风格(NASM,YASM): MASM风格(也包括T
[variable]
和variable
之间的区别一无所知。正如教程所说,两者都是指针,那么这有什么意义呢?为什么我必须在[]
之前使用类型标识符
?
我的汇编程序:
nasm x86\u 64在Linux-->Ubuntu上运行在x86英特尔语法中[expression]
表示地址expression
处的内存内容
(在MASM中,当表达式
是数值文字或eq
常量且无寄存器时除外)
表达式
不带括号取决于您使用的汇编程序
NASM风格(NASM,YASM):
MASM风格(也包括TASM,甚至GCC/GAS。英特尔语法noprefix
):
GAS(AT&T语法):它不是Intel语法,请参阅。GAS还使用不同的指令(如.byte
而不是db
),即使在.intel\u语法
模式下也是如此
在所有情况下,变量
都是标记内存中标签出现的特定位置的符号别名。因此:
variable1 db 41
variable2 dw 41
label1:
在符号表中生成三个符号,variable1
、variable2
和label1
当您在代码中使用它们中的任何一个时,例如mov eax,
,它不知道它是由db
或dw
定义的,还是作为标签的,因此当您使用mov[variable1],ebx
(在定义的第一个字节之外覆盖3个字节)时,它不会给您任何警告
它只是内存中的一个地址
(在MASM中除外,在MASM中,数据段中标签后的db或dd与“变量名”相关联。)
当无法从指令操作数本身推断类型时,大多数汇编程序只需要类型标识符
mov [ebx],eax ; obviously 32 bits are stored, because eax is 32b wide
mov [ebx],1 ; ERROR: how "wide" is that immediate value 1?
mov [ebx],WORD 1 ; NASM syntax (16 bit value, storing two bytes)
mov WORD [ebx],1 ; NASM syntax (16 bit value, storing two bytes)
mov WORD PTR [ebx],1 ; MASM/TASM syntax
使用寄存器和指针的一个小示例:
mov eax,10
表示:将值10移入寄存器eax。在本例中,EAX仅用于存储某些内容。EAX包含什么对程序员来说根本不重要,因为它无论如何都会被擦除
mov[eax],10
表示:将值10移动到存储在eax寄存器中的地址中。在这种情况下,存储在EAX中的值对我们来说非常重要,因为它是一个指针,这意味着我们必须进入EAX寄存器并查看其中包含的内容,然后使用该值作为访问地址
使用指针时需要两个步骤:
转到EAX,查看它包含的值(例如EAX=0xBABA)
转到EAX指向的地址(在我们的例子中是0xBABA)并在其中写入10
当然,指针不一定要用寄存器,这个小例子只是解释它是如何工作的。
< P>既然你已经知道C++,我将通过向你展示这些表达式的C等价物来回答。
当你写作时
[variable]
在汇编中,它相当于
*variable
在C中,也就是说,将变量
视为指针,并取消引用该指针-获取指针指向的值
类似地,“类型标识符”类似于将指针投射到不同的类型:
ASM:
dword ptr [variable]
C:
*((uint32_t*) variable)
ASM:
word ptr [variable]
C:
*((uint16_t*) variable)
我希望这有助于你理解这些表达的含义
(本节所指补遗已从原问题中删除)
我不完全确定您在“转换为ascii”时遇到了什么问题,但我怀疑您只是对它在输出或其他方面的视觉呈现方式感到困惑
例如,如果您有这样的代码:
myInteger db 41
mov AL, byte ptr [myInteger]
mov
将值41
从存储器复制到AL
寄存器中。数字41
恰好是)
字符的ascii表示形式,但这不会改变任何东西。值是解释为ascii字符还是整数取决于您,因为它们是相同的值。您以前使用过C吗?还是其他系统编程语言?(如果我们了解了您先前的知识,它将帮助我们给出您可以理解的答案)您使用的是什么汇编程序?您正在学习什么类型的装配?有很多种,我可以编程PASCAL和C++。我知道如何使用指针,我正在使用64位版本的Nasm汇编程序。对不起,我没有告诉:)@MichaelPetch:这一个似乎更多的是关于符号名而不是寄存器。这里的答案没有提到mov eax,sym作为mov immediate。他们是高度相关的,但我认为他们都需要相互联系,以获得对这两个问题的完整答案。我认为这个问题可能是更好的规范问题,因为简单,但是IDK。我在我的文章中提到了一些NASM与MASM的内容,其中也包括寄存器直接(非内存)操作数。好的,这很有帮助。谢谢。但是对于整数ASCII问题(在顶部描述):你有线索吗?这是一个QA网站,不是一个论坛。这意味着通常每个线程有一个问题。我强烈建议您编辑您的问题并删除第二个问题,然后用新问题打开一个新线程。mov将把值41从内存复制到AL寄存器中。数字41恰好是字符的ascii表示形式,但这不会改变任何东西。值是解释为ascii字符还是整数取决于您,因为它们是相同的值。是的,但我想让用户看到'41'。我该怎么做?顺便说一句:很好answer@TheFrenchPlaysHdMicraftn:您必须生成两个(或更多)字节,这些字节将保存字符“4”和“1”(正好是0x34和0x31)的ASCII值。因此,一种可能性是取41
并将其除以10直到零,用余数(或余数,0x30
获得ASCII数字)从头到尾构建字符串
ASM:
dword ptr [variable]
C:
*((uint32_t*) variable)
ASM:
word ptr [variable]
C:
*((uint16_t*) variable)
myInteger db 41
mov AL, byte ptr [myInteger]