使用从EXTERN操作码获得的数据

时间:2017-04-24 02:27:45

标签: assembly global extern

为了流利地使用漂亮的汇编语言,我想不出一个更好的方法来将我的脚趾浸入中级组装,而不是完全理解我从一开始就遇到的问题的细节。很可能在我的初学者的书中逐步解释了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的精确副本。这与段寄存器有关吗?如果涉及段寄存器,将会非常感谢您完全了解正在发生的事情。

1 个答案:

答案 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}}