Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 汇编代码无法识别?和@数据_Linux_Assembly_X86_Nasm - Fatal编程技术网

Linux 汇编代码无法识别?和@数据

Linux 汇编代码无法识别?和@数据,linux,assembly,x86,nasm,Linux,Assembly,X86,Nasm,这是我的第一个汇编程序。 请任何人帮助它成功运行。 我看到下面的编译错误 为什么它不承认这一点?和@数据? 我试图在汇编中交换两个变量 我正在执行以下命令 nasm -f elf swap.asm 但我得到了这个错误: swap.asm:6: error: symbol `?' undefined swap.asm:12: error: symbol `@data' undefined swap.asm:15: error: invalid combination of opcode and

这是我的第一个汇编程序。 请任何人帮助它成功运行。 我看到下面的编译错误

为什么它不承认这一点?和@数据? 我试图在汇编中交换两个变量

我正在执行以下命令

nasm -f elf swap.asm
但我得到了这个错误:

swap.asm:6: error: symbol `?' undefined
swap.asm:12: error: symbol `@data' undefined
swap.asm:15: error: invalid combination of opcode and operands
swap.asm:21: error: invalid combination of opcode and operands
swap.asm:22: error: invalid combination of opcode and operands
这是我的代码:

section .data
    C equ 15
    var1 db 12

section .bss
    var2 db ?

section .code
    global _start
    _start:

    mov ax, @data
    mov ds, ax

    mov var2, C

    ; swap var1 and var2

    mov al, var1
    mov bl, var2
    mov var2, al
    mov var1, bl

    ; now print the swapped values
    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var1
    mov edx, 8
    int 80h

    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var2
    mov edx, 8
    int 80h

    ; exit the program
    mov eax, 1  ; 1 = sys_exit
    mov ebx, 0
    int 80h

此代码表示您可能从MASM教程中复制并粘贴了16位代码:

mov ax, @data
mov ds, ax
在Linux上,模型是扁平的,因此此代码是不必要的,可以删除。由于您是使用NASM编译的,因此当您希望访问内存地址处的数据时,必须将[]放在内存引用周围,这与MASM不同。所以代码如下:

mov al, var1
应该是:

mov al, [var1]
在第2.2节MASM用户快速入门中,提供了有关NASM和MASM语法之间差异的有用信息。我已在本修订规范中记录了许多其他要求的变更:

section .data
    C equ 15
    var1: db 12                ; NASM needs a colon after labels unlike MASM

section .bss
    var2: resb 1               ; NASM doesn't have '?'. Use RESB to allocate space
                               ; in BSS section. RESB 1 allocates 1 byte of space

section .text                  ; The code section in ELF is `.text` and not `.code`
    global _start
    _start:

    mov byte [var2], C         ; C doesn't need brackets because it was defined with EQU
                               ;     and is a constant (immediate) value.
                               ;     NASM can't determine the size of a constant
                               ;     nor does it know the size of data at var2
                               ;     so the BYTE directive is used on the memory operand.

    ; swap var1 and var2

    mov al, [var1]             ; Getting data from var1 - brackets needed
    mov bl, [var2]             ; Getting data from var2 - brackets needed
    mov [var2], al             ; Changing value at var2 - brackets needed
    mov [var1], bl             ; Changing value at var1 - brackets needed

    ; now print the swapped values
    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var1              ; No brackets because we want the address of var1
    mov edx, 1                 ; Print 1 byte
    int 80h

    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var2              ; No brackets because we want the address of var1

    mov edx, 1                 ; Print 1 byte
    int 80h

    ; exit the program
    mov eax, 1  ; 1 = sys_exit
    mov ebx, 0
    int 80h

如果您运行此代码,它可能看起来没有打印您期望的内容。SYS_write系统调用不打印整数-它打印字符串。如果要写入值12或15,则需要将数字转换为字符串,然后将字符串的地址传递给SYS_write系统调用。对于将整数转换为字符串的32位解决方案,您可以查看其答案。Peter Cordes的另一个相关答案还有其他。

此代码表示您可能从MASM教程中复制并粘贴了16位代码:

mov ax, @data
mov ds, ax
在Linux上,模型是扁平的,因此此代码是不必要的,可以删除。由于您是使用NASM编译的,因此当您希望访问内存地址处的数据时,必须将[]放在内存引用周围,这与MASM不同。所以代码如下:

mov al, var1
应该是:

mov al, [var1]
在第2.2节MASM用户快速入门中,提供了有关NASM和MASM语法之间差异的有用信息。我已在本修订规范中记录了许多其他要求的变更:

section .data
    C equ 15
    var1: db 12                ; NASM needs a colon after labels unlike MASM

section .bss
    var2: resb 1               ; NASM doesn't have '?'. Use RESB to allocate space
                               ; in BSS section. RESB 1 allocates 1 byte of space

section .text                  ; The code section in ELF is `.text` and not `.code`
    global _start
    _start:

    mov byte [var2], C         ; C doesn't need brackets because it was defined with EQU
                               ;     and is a constant (immediate) value.
                               ;     NASM can't determine the size of a constant
                               ;     nor does it know the size of data at var2
                               ;     so the BYTE directive is used on the memory operand.

    ; swap var1 and var2

    mov al, [var1]             ; Getting data from var1 - brackets needed
    mov bl, [var2]             ; Getting data from var2 - brackets needed
    mov [var2], al             ; Changing value at var2 - brackets needed
    mov [var1], bl             ; Changing value at var1 - brackets needed

    ; now print the swapped values
    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var1              ; No brackets because we want the address of var1
    mov edx, 1                 ; Print 1 byte
    int 80h

    mov eax, 4  ;   4 = sys_write
    mov ebx, 1  ;   1 - std out FD
    mov ecx, var2              ; No brackets because we want the address of var1

    mov edx, 1                 ; Print 1 byte
    int 80h

    ; exit the program
    mov eax, 1  ; 1 = sys_exit
    mov ebx, 0
    int 80h

如果您运行此代码,它可能看起来没有打印您期望的内容。SYS_write系统调用不打印整数-它打印字符串。如果要写入值12或15,则需要将数字转换为字符串,然后将字符串的地址传递给SYS_write系统调用。对于将整数转换为字符串的32位解决方案,您可以查看其答案。Peter Cordes的另一个相关答案还有另外一个。

您有16位代码和32位代码的混合,其中一些代码是MASM语法,其余的是NASM。我认为下面两条指令的操作数大小不同。解决方案应该是什么?我应该使用cl而不是ecx吗?mov ecx,var1 mov ecx,VAR2您有16位代码和32位代码的混合,其中一些代码是MASM语法,其余是NASM。我认为下面两条指令的操作数大小不同。解决方案应该是什么?我应该使用cl而不是ecx吗?mov ecx,var1 mov ecx,VAR2对于最后一部分,有at Does部分的工作代码。代码在这里实际工作吗?发现它不适用于x86-64 Linux,该未知节名被链接到一个不可执行的段中。可能ld默认值已更改,并且没有将.rodata放入文本段。嗯,我刚刚测试了这段代码,它确实用两个单独的系统调用写入了\17和\f字节,而不是segfaulting。我认为这段代码只在32位模式下工作,因为缺少一个PT_GNU__堆栈注释,导致仍然获得exec all,或者可能这只是execstack处理的一个副作用,在没有PT_GNU_堆栈的情况下,您可以在32位可执行文件中获得exec all,而不仅仅是x86-64中的exec堆栈:对于最后一部分,有at Does部分的工作代码。代码在这里实际工作吗?发现它不适用于x86-64 Linux,该未知节名被链接到一个不可执行的段中。可能ld默认值已更改,并且没有将.rodata放入文本段。嗯,我刚刚测试了这段代码,它确实用两个单独的系统调用写入了\17和\f字节,而不是segfaulting。我认为这段代码只在32位模式下工作,因为缺少一个PT_GNU__堆栈注释,导致仍然获得exec all,或者可能这只是execstack处理的一个副作用,在没有PT_GNU_堆栈的情况下,您可以在32位可执行文件中获得exec all,而不仅仅是x86-64中的exec堆栈: