Assembly 汇编语言中的数组
如果我必须把Assembly 汇编语言中的数组,assembly,x86,nasm,Assembly,X86,Nasm,如果我必须把short int v[5]={1,2,3,4,5}翻译成assemblycode,我该怎么做?如果我在做这样的事情,这没关系: Enter 16,0 Mov ebp-4, 1 Mov ebp-8, 2 Mov ebp-12, 3 Mov ebp-16, 4 谢谢。您可以这样做,但正如@Ped7g所指出的,您需要限定符。v[0]在内存中要少20个字节,因此您必须以相反的顺序写入它们 enter 20, 0 ; At this point ESP is the
short int v[5]={1,2,3,4,5}
翻译成assembly
code,我该怎么做?如果我在做这样的事情,这没关系:
Enter 16,0
Mov ebp-4, 1
Mov ebp-8, 2
Mov ebp-12, 3
Mov ebp-16, 4
谢谢。您可以这样做,但正如@Ped7g所指出的,您需要限定符。v[0]在内存中要少20个字节,因此您必须以相反的顺序写入它们
enter 20, 0
; At this point ESP is the pointer to v[]
mov dword [bp-20], 1
mov dword [bp-16], 2
mov dword [bp-12], 3
mov dword [bp-8], 4
mov dword [bp-4], 5
你必须使用德沃德的原因是因为想象一下堆栈的竞争,如下所示
2F 3D 17 0A 41 FF 16 18 03 22 19 0D 01 F3 D1 0C 12 02 EE 4A
对字节[bp-4]使用字节限定符,5将只更改2F。但是,DWORD会更改所有4个字节,然后变为
05 00 00
为了节省程序空间,您还可以
push bp
mov bp, sp
push 5
push 4
push 3
push 2
push 1
对此有一些注意事项,但由于IA32是结构化的,因此将扩展到32位。但使用的代码要少得多
在程序外声明,则它将成为
v: dw 1, 2, 3, 4, 5
你可以这样做,但正如@Ped7g所指出的,你需要限定符。v[0]在内存中要少20个字节,因此您必须以相反的顺序写入它们
enter 20, 0
; At this point ESP is the pointer to v[]
mov dword [bp-20], 1
mov dword [bp-16], 2
mov dword [bp-12], 3
mov dword [bp-8], 4
mov dword [bp-4], 5
你必须使用德沃德的原因是因为想象一下堆栈的竞争,如下所示
2F 3D 17 0A 41 FF 16 18 03 22 19 0D 01 F3 D1 0C 12 02 EE 4A
对字节[bp-4]使用字节限定符,5将只更改2F。但是,DWORD会更改所有4个字节,然后变为
05 00 00
为了节省程序空间,您还可以
push bp
mov bp, sp
push 5
push 4
push 3
push 2
push 1
对此有一些注意事项,但由于IA32是结构化的,因此将扩展到32位。但使用的代码要少得多
在程序外声明,则它将成为
v: dw 1, 2, 3, 4, 5
这是什么汇编程序语法?英特尔语法要求在内存引用周围使用
[]
(从操作数顺序看,它类似于英特尔语法)。每个汇编程序都有细微的差别,MASM:mov-word-ptr[ebp-4],1
,NASM:mov-word[ebp-4],1
。。。您可以将值相隔2个字节,因为short int
是int16\u t
(可能)。此外,如果您在内存中读取这些值,您将以@ebp-16地址结束:4,3,2,1。。。碳源为1,2,3,4,5。。。所以你很接近,但不一样,你有正确的原则,现在调整细节。试试看戈德博尔特:嘿,谢谢你。我想为NASM;)那么“v dw 1,2,3,4,5”呢?@Tommylee2k不能用于存储在堆栈中的局部变量,只能用于.data
中的全局/静态变量。Andreea:将“-fno omit frame pointer”添加到上一个链接中的gcc选项将强制其使用ebp
符号,更接近原始源代码:(如果您没有经验发现如何在第一个变量中利用esp
,那么您应该更容易理解这个变量->但我强烈建议将所有变量(包括-O3变量)复制到调试器中,并对它们进行一步推理,了解它们的差异以及每个变量的工作方式=将教会您很多)他没有说他想要的是数据的局部变量;-)tbh他没有指定任何东西。我们只是从他的代码片段中推断出这是什么汇编程序语法?英特尔语法要求在内存引用周围使用[]
(从操作数顺序看,它类似于英特尔语法)。每个汇编程序都有细微的差别,MASM:mov-word-ptr[ebp-4],1
,NASM:mov-word[ebp-4],1
。。。您可以将值相隔2个字节,因为short int
是int16\u t
(可能)。此外,如果您在内存中读取这些值,您将以@ebp-16地址结束:4,3,2,1。。。碳源为1,2,3,4,5。。。所以你很接近,但不一样,你有正确的原则,现在调整细节。试试看戈德博尔特:嘿,谢谢你。我想为NASM;)那么“v dw 1,2,3,4,5”呢?@Tommylee2k不能用于存储在堆栈中的局部变量,只能用于.data
中的全局/静态变量。Andreea:将“-fno omit frame pointer”添加到上一个链接中的gcc选项将强制其使用ebp
符号,更接近原始源代码:(如果您没有经验发现如何在第一个变量中利用esp
,那么您应该更容易理解这个变量->但我强烈建议将所有变量(包括-O3变量)复制到调试器中,并对它们进行一步推理,了解它们的差异以及每个变量的工作方式=将教会您很多)他没有说他想要的是数据的局部变量;-)tbh他没有指定任何东西。我们只是从他的代码片段中推断出这一点,您正在堆栈上定义v:dd1,2,3,4,5
。可以在堆栈内存中定义短数组,即使默认的push/pop
使用DWORD,您甚至可以使用push
,例如push 0x50004
push 0x30002
push 0x10000
将单词数组设置为原始esp-10
,并在esp-11和esp-12上使用2B垃圾(或者新的esp+0、esp+1和数组位于esp+2到esp+11之间)。如果您查看我的评论中的godbolt链接,C编译器确实会在堆栈中生成短数组(但通过使用mov
,而不是push
)。您正在堆栈上定义v:dd 1、2、3、4、5
。可以在堆栈内存中定义短数组,即使默认的push/pop
使用DWORD操作,您甚至可以使用push
,如push 0x50004
push 0x30002push 0x10000在原始esp中使用字数组-10
在esp-11和esp-12上有2B垃圾(或新的esp+0、esp+1,数组在esp+2到esp+11)。如果您想查看我的评论中的锁紧螺栓链接,C编译器确实会在堆栈中生成短数组(但通过使用mov
,而不是push
)。