此代码表明您可能已从 16 位代码的 MASM 教程中复制并粘贴了它:
mov ax, @data
mov ds, ax
在 Linux 上,模型是扁平的,因此这段代码是不必要的,可以删除。由于您正在使用 NASM 进行编译,因此您必须放置[]
当您希望访问内存地址处的数据时,围绕内存引用(与 MASM 不同)。所以代码如下:
mov al, var1
应该:
mov al, [var1]
The NASM 文档 https://nasm.us/doc/nasmdoc2.html部分中有关于 NASM 和 MASM 语法之间差异的有用信息2.2 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 位解决方案,您可以查看此问题的答案相关问题 https://stackoverflow.com/questions/19309749/nasm-assembly-convert-input-to-integer/49548057#49548057。 Peter Cordes 的另一个相关答案还有其他有用的信息 https://stackoverflow.com/a/46301894/3857942.