如何在GNU x86中初始化变量?你如何编译和运行它们?我到处搜索,但找不到合适的教程。这是我的代码。我也不确定我的语法是否正确,因为我仍然无法测试它们
section .data
number db 'Enter ten numbers: ', 10
numberLen equ $-number
i dw 0
section .bss
digits resw 10
section .text
global _start
_start:
movw $0, %esi
movl $4, %eax
movl $1, %ebx
movl $number, %ecx
movl $32, %edx
int $0x80
for:
cmpsw $10, (%i)
jge skip
movl $3, %eax
movl $0, %ebx
lea digits(%esi), %ecx
movl $2, %edx
int $0x80
subw $0x30, digits(%esi)
incw %esi
incw %i
jmp for
skip:
pushw %digits
pushw %i
call sort
movb $0, %esi
movw $0, %i
print:
cmpsw $10, (%i)
jge exit
addw $0x30, digits(%esi)
movl $4, %eax
movl $1, %ebx
lea digits(%esi), %ecx
movl $1, %edx
int $0x80
incw %esi
incw %i
jmp print
exit:
movl $1, %eax
movl $0, %ebx
int $0x80
sort:
movw %esp, %ebp
movb $0, %esi
for2:
movw $0, %edi
cmpsw $10, (%esi)
jge after
for3:
movw digits(%edi), %al
cmpsw (%edi), (%esi)
jl cmp2
cmp1:
cmpsw (%al), digits(%esi)
jmp continue
cmp2:
cmpsw digits(%esi), (%al)
continue:
jge next
movw digits(%esi), %bl
movw digits(%edi), %al
movw %al, digits(%esi)
movw %bl, digits(%edi)
next:
cmpsw $10, (%esi)
jge next2
incw %edi
jmp for3
next2:
incw %esi
jmp for2
after:
ret 6
答案 0 :(得分:1)
初始化变量
您可以在.data
部分初始化变量。你通常这样做:
label: .directive values...
例如,listofnumbers: .byte 1, 2, 3, 4, 5, 6
有一个list of "pseudo-ops",其中包含.ascii
,.byte
等数据定义指令。
您使用listofnumbers
在代码中引用$listofnumbers
的地址,使用listofnumbers
引用地址中的值。因此movl $listofnumbers, %eax
会将listofnumbers
的地址放在eax
寄存器中,movb listofnumbers, %al
会将字面值1
放在{{1}的低位字节中注册。
编译代码
要将eax
编译为可执行文件filename.S
,我建议:
filename
gcc -nostdlib -g -o filename filename.S
阻止gcc尝试链接寻找-nostdlib
函数的标准库例程。
main
使用调试符号编译代码。这意味着您可以使用gdb(-g
)运行代码,设置断点,并在gdb内部逐步执行代码(例如gdb filename
,break 1
,run
。在gdb中,step
和info reg
将让您查看寄存器和堆栈周围的内存区域。
您可以使用简单的x/100xw $ebp-50
来运行您的代码,但我建议使用./filename
因为它会让很多更容易看到当您意外发生时会发生什么结果