Gcc 关于IA32汇编语言函数的几个问题
我正在用汇编语言编写计算降雪量的代码。它要求用户输入do while循环中的降雪量(以英寸为单位),直到用户输入0打破循环。同样在循环中,数量也会相互相加。输入0后,程序将以英尺和英寸为单位打印降雪总量 我的程序有三个函数:printStr、readUInt和printUInt以及我的main。我理解printStr和readUInt是如何工作的,但我不理解printUInt是如何工作的,所以我希望有人能向我解释一下 此外,当我必须打印“总降雪量:#英尺和#英寸”时,我很难确定如何打印字符串中的两个数字,关于这一点的一些建议也会有所帮助 我已经为此工作了好几个小时,如果我不是完全被难倒的话,我就不会在这里了 printStr(edi=要打印的以null结尾的字符串的地址) 打印单元(edi=要打印的无符号整数): readUInt(返回%eax中读取的无符号整数) 主要数据:Gcc 关于IA32汇编语言函数的几个问题,gcc,assembly,att,x86,Gcc,Assembly,Att,X86,我正在用汇编语言编写计算降雪量的代码。它要求用户输入do while循环中的降雪量(以英寸为单位),直到用户输入0打破循环。同样在循环中,数量也会相互相加。输入0后,程序将以英尺和英寸为单位打印降雪总量 我的程序有三个函数:printStr、readUInt和printUInt以及我的main。我理解printStr和readUInt是如何工作的,但我不理解printUInt是如何工作的,所以我希望有人能向我解释一下 此外,当我必须打印“总降雪量:#英尺和#英寸”时,我很难确定如何打印字符串中的
.data
AskSF: .asciz "How many inches of snow to add (0 when done): "
TotalSF: .asciz "Total snowfall: %d feet and inches "
.text
主要内容:
打印单元例程的工作原理如下:
printUInt:
pushq %rbp
movq %rsp,%rbp
subq $24,%rsp
movl %ebx, -4(%rbp)
movl %edi, -8(%rbp)
movl $10, -12(%rbp) # Constant 10 used for division/modulus
movl %edi, %eax # eax = digits left to convert
movl $printUIntBufferEnd,%ecx # %ecx is the insert point
# Convert each digit into a characters
printUInt_loop:
movl $0, %edx # Reset high portion for division
divl -12(%rbp) # Divide edx:eax by 10; edx=Remainder / eax = quotient
addb $'0',%dl
movb %dl,0(%ecx)
subl $1,%ecx
testl %eax,%eax
jnz printUInt_loop
# Done with loop, print the buffer
movl %ecx,%edi
addl $1,%edi
call printStr
printUInt_end:
movl $-1,%eax
movl $-1,%ecx
movl $-1,%edx
movl -8(%rbp), %edi
movl -4(%rbp), %ebx
leave
ret
.data
readUInt_bufferStart = .
readUInt_buffer: .ascii " "
.text
readUInt:
pushq %rbp # Save the old rpb
movq %rsp, %rbp # Setup this frames start
movl %ebx,-4(%rbp)
movl $0,%eax # initialize accumulator
readUInt_next_char:
# Read a character
movl %eax,-8(%rbp)
movl $3, %eax # issue a read
movl $1,%ebx # File descriptor 1 (stdin)
movl $1,%edx # sizet = 1 character
movl $readUInt_bufferStart,%ecx
int $0x80 # Syscall
movl -8(%rbp),%eax
# Get the character
movb readUInt_bufferStart,%bl
cmpb $'0',%bl
jb readUInt_end
cmpb $'9',%bl
ja readUInt_end
movl $10,%edx
mul %edx
subb $'0',%bl
addl %ebx,%eax
jmp readUInt_next_char
readUInt_end:
movl $-1,%ecx
movl $-1,%edx
movl -4(%rbp),%ebx
leave
ret
.data
AskSF: .asciz "How many inches of snow to add (0 when done): "
TotalSF: .asciz "Total snowfall: %d feet and inches "
.text
do_while:
movl $AskSF, %edi
call printStr #asking for amount of snowfall
call readUInt
addl %eax,%edx #adding amounts of snowfall together
movl %eax,%ecx #moving entered amount to compare with 0
cmpl $0,%ecx # checking if amount is 0 to see if loop should exit
jne do_while
#below here I was just experimenting looking for solutions
movl $TotalSF,%edi
call printStr
movl %edx,%edi
call printUInt
.data
TotalSF1: .asciz "Total snowfall: "
TotalSF2: .asciz " feet and "
TotalSF3: .asciz " inches\n"
.text
do_while:
movl $AskSF, %edi
call printStr
call readUInt
addl %eax, %ebx # %ebx doesn't get clobbered
# by function calls, so use it for sum
movl %eax, %ecx
cmpl $0, %ecx
jne do_while
movl $TotalSF1, %edi # print the first bit of the answer
call printStr
xor %edx, %edx # zero out %edx in prep for division
movl $12, %ecx # number of inches in a foot (imperialist!)
movl %ebx,%eax # put total snowfall in %eax
divl %ecx # divide %edx:%eax by 12 to get ft + in
push %edx # put inches on the stack to keep it safe
movl %eax, %edi # print out feet
call printUInt
movl $TotalSF2, %edi # print out the middle bit of the answer
call printStr
pop %edi # print out inches
call printUInt
movl $TotalSF3, %edi # print closing bit of answer
call printStr
movl $1, %eax # exit nicely
movl $0, %ebx
int $0x80