在 Linux 上使用 x86 汇编和 at&t 打印计数器 0 --> 4
Print counter 0 --> 4 using x86 assembly and at&t on Linux
我想打印一个循环的计数器 (0 --> 4)。在下面的代码中,diff 是 '0' 字符的 ASCII 数,最大循环重复次数,计数计数器和 p 是包含该字符的变量。
.data
.text
.global main
diff = 48
max = 5
count: .byte 0
p: .long 0
main:
compare:
cmpb $max,count # if counter is equal or above max
jae end # jump to end
movl ,%eax # write
movl ,%ebx # stdout
xor %ecx,%ecx # reset ecx
addb $diff,%cl # add ASCII number of '0'
addb count,%cl # add value of counter
movb %cl,p # move ASCII value of the counter
movl $p,%ecx # move the number to third argument of write
movl ,%edx # size of long
int [=11=]x80 # interrupt
movb count,%al # move value of the counter to al
inc %al # increment al
movb %al,count # move value of al to counter
jmp compare # always jump to compare
end:
movl ,%eax # exit
movl [=11=],%ebx # exit(0)
int [=11=]x80 # interrupt
没用。 gcc 不会给我错误,但执行它会给出核心转储。为什么?
您的变量 count
和 p
是在 .text
指令之后定义的,这意味着它们在 text
部分中。此部分应该用于代码并且是只读的。因此,尝试写入这些位置会导致段错误。
您可能想按照 .data
指令定义它们。
修复这个问题后,看起来程序可以运行,但实际上还有另一个错误。在每次循环迭代中,您使用 4 个字节调用 write
,整个 long
。高位字节为 0。因此,不是写入一个字节,ascii 0 (0x30),而是写入 4 个字节 (0x30 0x00 0x00 0x00)。您的程序总共输出 20 个字节而不是 5 个。
您可能只想写入一个字节。在这种情况下,您可能希望在调用 write
时将 %edx
设置为 1。在这种情况下,p
可以只是 .byte
而不是 .long
.
顺便说一下,如果您 运行 在调试器(例如 gdb)下执行此操作,您将立即看到哪个指令出错。如果你没有这样做,你应该!知道如何使用调试器对于任何语言的程序员来说都是必不可少的,尤其是汇编语言。
如果你这样做了,最好在你的问题中包含这些信息。
我想打印一个循环的计数器 (0 --> 4)。在下面的代码中,diff 是 '0' 字符的 ASCII 数,最大循环重复次数,计数计数器和 p 是包含该字符的变量。
.data
.text
.global main
diff = 48
max = 5
count: .byte 0
p: .long 0
main:
compare:
cmpb $max,count # if counter is equal or above max
jae end # jump to end
movl ,%eax # write
movl ,%ebx # stdout
xor %ecx,%ecx # reset ecx
addb $diff,%cl # add ASCII number of '0'
addb count,%cl # add value of counter
movb %cl,p # move ASCII value of the counter
movl $p,%ecx # move the number to third argument of write
movl ,%edx # size of long
int [=11=]x80 # interrupt
movb count,%al # move value of the counter to al
inc %al # increment al
movb %al,count # move value of al to counter
jmp compare # always jump to compare
end:
movl ,%eax # exit
movl [=11=],%ebx # exit(0)
int [=11=]x80 # interrupt
没用。 gcc 不会给我错误,但执行它会给出核心转储。为什么?
您的变量 count
和 p
是在 .text
指令之后定义的,这意味着它们在 text
部分中。此部分应该用于代码并且是只读的。因此,尝试写入这些位置会导致段错误。
您可能想按照 .data
指令定义它们。
修复这个问题后,看起来程序可以运行,但实际上还有另一个错误。在每次循环迭代中,您使用 4 个字节调用 write
,整个 long
。高位字节为 0。因此,不是写入一个字节,ascii 0 (0x30),而是写入 4 个字节 (0x30 0x00 0x00 0x00)。您的程序总共输出 20 个字节而不是 5 个。
您可能只想写入一个字节。在这种情况下,您可能希望在调用 write
时将 %edx
设置为 1。在这种情况下,p
可以只是 .byte
而不是 .long
.
顺便说一下,如果您 运行 在调试器(例如 gdb)下执行此操作,您将立即看到哪个指令出错。如果你没有这样做,你应该!知道如何使用调试器对于任何语言的程序员来说都是必不可少的,尤其是汇编语言。
如果你这样做了,最好在你的问题中包含这些信息。