为了流利地使用漂亮的汇编语言,我想不出一个更好的方法来将我的脚趾浸入中级组装,而不是完全理解我从一开始就遇到的问题的细节。很可能在我的初学者的书中逐步解释了Jeff Duntemann的汇编语言:
我有一个文件hexlib.asm,它使用以下命令组装并生成其hexlib和hexlib.o副本:
nasm -f elf -g -F stabs hexlib.asm
ld -o hexlib hexlib.o -melf_i386
asm文件包含以下基本代码:
GLOBAL TestString
SECTION .data
TestString db 'Gewurztraminer'
SECTION .bss
SECTION .text
;_start is omitted because the main.asm file already uses it.
;I got a warning from NASM, but, like any novice, I ignored it
;because I have enough on my mind already.
我也有main.asm,它使用以下命令:
nasm -f elf -g -F stabs main.asm
ld -o main main.o libraries/hexlib/hexlib.o -melf_i386
和main.asm文件中的代码如下: (我正在寻求为我的公司建造一台我希望销售的机器,所以请原谅所有权利保留。
;#################################################################
;#################################################################
;## ##
;## ************************************ ##
;## * AUTHOR: cvgbhfghfhf * ##
;## * ALL RIGHTS RESERVED * ##
;## ************************************ ##
;## _________________________________________________________ ##
;## | |_REGISTER_|_________CONTAINS_________| ##
;## | | | | ##
;## | INPUT REGISTERS | | | ##
;## | | | | ##
;## |___________________|__________|__________________________| ##
;## _________________________________________________________ ##
;## | |_REGISTER_|_________CONTAINS_________| ##
;## | | | | ##
;## | OUTPUT REGISTERS | | | ##
;## | | | | ##
;## |___________________|__________|__________________________| ##
;## ##
;## _________________________________________________________ ##
;## | | | ##
;## | DESCRIPTION | | ##
;## | OF FUNCTION | | ##
;## |___________________|_____________________________________| ##
;## | | | ##
;## | PROCEDURES | | ##
;## |___________________|_____________________________________| ##
;## ##
;#################################################################
;#################################################################
;########## Build using these commands ##########
;nasm -f elf -g -F stabs main.asm
;ld -o main main.o libraries/declib/declib.o -melf_i386
;################################################
EXTERN TestString
SECTION .data ; Section containing initialised data. <=============
TestStringLen equ $-TestString
SECTION .bss ; Section containing uninitialized data. <===========
SECTION .text ; Section containing the code of procedures. <=======
Display:
mov eax, 4
mov ebx, 1
mov ecx, TestString
mov edx, TestStringLen
int 80h
Done: mov eax, 1
mov ebx, 0
int 80h
global _start ; Linker needs this to find the entry point. <=======
_start:
nop ; GDB requirement. <=================================
call Display
call Done
;+~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*+
;* INPUT REGISTERS: *
;~ ~
;* OUTPUT REGISTERS: *
;~ ~
;* DESCRIPTION: *
;~ ~
;+~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*+
当我尝试组装main.asm时,出现以下错误:
~/assembly$ nasm -f elf -g -F stabs main.asm
main.asm:46: error: invalid operand type
第46行是:
TestStringLen equ $-TestString
我的问题是:究竟发生了什么?显然,TestString不是我在hexlib.asm中初始化的TestString的精确副本。这与段寄存器有关吗?如果涉及段寄存器,将会非常感谢您完全了解正在发生的事情。
答案 0 :(得分:1)
究竟发生了什么?
您的代码中存在两个问题:
第一个是不支持给定的重定位类型。这是什么意思?
让我们看一下以下代码:
mov eax, 30
汇编程序将从汇编程序文件创建目标文件(.o或.obj)。在目标文件中,存储以下代码:
extern test1
mov eax, test1+20
现在让我们看一下以下代码:
mov eax, 20
在目标文件中存储以下代码:
$ - TestString
另外还有一个&#34;搬迁&#34; (存储&#34; ld&#34;所理解的特殊数据项),它告诉链接器(&#34; ld&#34;)&#34; test1&#34;的地址(或值)。一旦知道此地址,就必须将其添加到数字20中。
根据所使用的文件格式,支持某些操作(例如将地址添加到值),而不支持其他操作。我知道的任何文件格式都不支持从mov edx, TestStringLen
这样的值中减去地址。
所以&#34; nasm&#34;是不可能的。为指令mov edx, 0
生成代码:在.o或.obj文件中,这将产生指令TestString
和一个&#34; ld&#34;必须从值0中减去SomeText db "Test"
SomeOtherItem db "Hello"
AThirdItem db "World!"
SomeTextLength equ $-SomeText
的地址。但是文件格式不支持类型的输入&#34;从...中减去地址。&#34;。
第二个是你不知道&#34; ld&#34;将放置第二个数据部分。
请记住以下代码......
SomeTextLength
...不会导致$-SomeText
的值为4但值为15.这是因为SomeText
表示:从TestStringLen
到这个行。字节数为4(&#34;测试&#34;)+ 5(&#34; Hello&#34;)+ 6(&#34;世界!&#34;)= 15。
当两行在.o或.obj文件中时,你有无控制有多少字节&#34;在&#34;之间两条线因为&#34; ld&#34;可以将属于不同目标文件的代码放在内存中的任何位置!
所以即使你使用了支持这种重定位的某种(假设的)文件格式,GLOBAL SomeText
GLOBAL SomeTextLen
...
SomeText db "Mein Beispieltext"
SomeTextLen equ $-SomeText
的值也不会是你期望的值!
那该怎么办?
不幸的是我不知道&#34; nasm&#34;但是其他汇编程序允许生成绝对符号&#34;。
在这种情况下,在一个文件中执行以下操作:
EXTERN SomeText
EXTERN SomeTextLen
在另一个文件中只需:
GLOBAL SomeText
GLOBAL SomeTextLen
...
SomeText db "Mein Beispieltext"
SomeTextLen dd $-SomeText
如果&#34;绝对符号&#34;不支持您必须这样做:
EXTERN SomeText
EXTERN SomeTextLen
...
mov EDX, [SomeTextLen]
和
{{1}}