Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用IA32汇编语言处理函数的几个问题

用IA32汇编语言处理函数的几个问题
EN

Stack Overflow用户
提问于 2014-11-11 21:13:11
回答 1查看 323关注 0票数 1

我正在用汇编语言编写计算降雪的代码。它要求用户提供在执行循环中下雪的数量(以英寸为单位),直到用户输入0才能打破循环。同样在循环中,金额是彼此相加的。一旦输入0,程序就应该打印总降雪量(以英尺和英寸为单位)。

我的程序有三个函数给我: printStr、readUInt和printUInt以及我的主程序。我理解printStr和readUInt是如何工作的,但我不明白printUInt是如何工作的,所以我希望有人能向我解释这一点。

另外,当我不得不打印“总降雪量:#英尺和#英寸”时,我很难弄清楚如何在字符串中打印这两个数字,关于这一点的一些建议也是有帮助的。

我已经为此做了几个小时了,如果我不是完全困惑的话,我就不会在这里了。

printStr (edi =要打印以空结尾的字符串的地址)

代码语言:javascript
运行
AI代码解释
复制
    printStr:
  pushq %rbp
  movq %rsp,%rbp
  subq $24,%rsp
  movl %ebx, -4(%rbp)

  movl %edi, %ecx   # Copy the "Start"

printStr_loop: 
  movb (%ecx),%al
  cmpb $0,%al
  jz   printStr_end 

  # Syscall to print a character
  movl $4, %eax     # Print (write) syscall
  movl $1, %ebx     # Screen (file)
#  movl $Hello, %ecx
  movl $1, %edx     # One character
  int $0x80

  addl $1, %ecx    
  jmp printStr_loop

printStr_end:
  movl $-1,%eax
  movl $-1,%ecx
  movl $-1,%edx
  movl -4(%rbp), %ebx
  leave
  ret

.data
printUIntBuffer: .asciz "          "
printUIntBufferEnd=.-2

.text

printUInt (edi =要打印的无符号整数):

代码语言:javascript
运行
AI代码解释
复制
    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 (返回%eax中读取的无符号int )

代码语言:javascript
运行
AI代码解释
复制
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

主要数据:

代码语言:javascript
运行
AI代码解释
复制
    .data


AskSF: .asciz "How many inches of snow to add (0 when done): "
TotalSF: .asciz "Total snowfall: %d feet and inches "


.text

主要:

代码语言:javascript
运行
AI代码解释
复制
    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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-12 00:55:23

printUInt例程的工作方式如下:

  1. 取整数(最初在%edi中,但在%eax中)
  2. 重复将其除以10,并找到余数(除数后在%edx中找到)。这个余数是被除数的最后一个数字,或者是最右边的数字.
  3. 将"0“的ASCII代码添加到这个最右边的数字中,以获得该数字的ASCII代码。
  4. 将结果值存储在%ecx所指向的内存中,并减少%ecx (字符串从右到左放置在内存中)。
  5. 重复直到商数(%eax)为零为止,这意味着所有的数字都打印出来了。
  6. 调用打印例程,指向内存中字符串中的第一个数字。

例如:

  1. 从%edx:%eax = 0:113开始
  2. 除以10:%eax = 11,%edx =3
  3. 加48至3: 51 (或ASCII "3")
  4. 将51存储在字符串所在的内存位置(现在是“3")。
  5. 除以10:%eax = 1,%edx =1
  6. 加48至1: 49 (ASCII "1")
  7. 字符串存储49 (现为“13")
  8. 除以10:%eax = 0,%edx =1
  9. 加48至1: 49 (ASCII "1")
  10. 字符串存储49 (现为“113")
  11. 停止,因为%eax =0
  12. 打印字符串。

为了以英尺和英寸来打印你的答案,我建议将任务分解成4个打印指令,获得了英尺和英寸的组件,并将它们放在堆栈上:

  1. 使用printStr例程打印“总降雪量:”
  2. 打印脚(从堆栈中检索脚值并在调用printUInt之前放入%edi )
  3. 使用printStr例程打印“和”
  4. 打印英寸(从堆栈中检索英寸值并放入%edi.)

像这样的东西应该能起作用(但可能更干净):

代码语言:javascript
运行
AI代码解释
复制
.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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26879728

复制
相关文章
Docker常见的几个问题处理
问题起因 由于公司最开始的服务器在/var/lib/docker没有挂载存储,容量只有40G,导致服务器磁盘用满。现将原有的Docker目录数据进行迁移。
Yuou
2022/09/26
7150
深入理解计算机系统(3.2)------程序编码以及数据格式
本文介绍了如何利用IA32架构进行程序开发,包括变量、常量、指令、数据格式等基本概念,以及程序执行流程的概述。同时,本文还介绍了IA32架构的存储器模型和程序示例,以帮助读者更好地理解程序设计和执行过程。
IT可乐
2018/01/04
8610
深入理解计算机系统(3.2)------程序编码以及数据格式
用向量做Mantel的几个问题
我测试了一下果然如此。把435随机换成其他几个数也会报错。 这时候开始有点意思了。难道435这个数存在什么特别之处么。 函数说明中没有提到这个报错,我在网上搜了一下也没有找到答案。
Listenlii-生物信息知识分享
2020/09/22
1.2K0
汇编语言比较指令cmp怎么用_汇编语言cmp指令怎么用
刚刚看到了cmp指令,一开始有点晕。后来上网找了些资料,终于看明白了,为了方便初学者,我就简单写下我的思路吧。高手绕过,谢谢!
全栈程序员站长
2022/11/07
2K0
trim-galore并行处理时的几个问题
config是需要进行处理的文件列表 trim_galore命令这里用的也比较简单,总结下处理时遇到的问题
Y大宽
2019/06/14
2.9K0
5.5 汇编语言:函数调用约定
函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等。
王瑞MVP
2023/10/11
2850
5.5 汇编语言:函数调用约定
函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等。
王瑞MVP
2023/08/22
3460
8086汇编语言——处理字符串
;将'basic'转成大写'BASIC' ;将'ASM'转成小写'asm' assume cs:code data segment db 'basic' db 'ASM' data ends code segment start: mov ax,data mov ds,ax ;设置ds指向data mov bx,0 ;设置偏移地址 mov cx,5 ;循环5次 s1: mov al,[bx]
zy010101
2020/10/10
8560
8086汇编语言——处理字符串
8086汇编语言之函数的声明和调用
由于print函数默认执行,为了保证在call时才执行, 咱们将print函数代码移至中断后:
乱码三千
2021/08/24
1.5K0
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或者更准确的说,各种汇编指令都是在操作什么样的对象。
YGingko
2018/09/30
3650
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
WebSocket :用WebSocket实现推送你必须考虑的几个问题
本项目通过WebSocket实现同时在线用户量几千的推送服务器(可内网运行)。且可实时查看用户在线状态。
全栈程序员站长
2022/09/14
1.6K0
汇编语言关于2号功能函数的坑点
也可以参考如下文章: http://www.delorie.com/djgpp/doc/rbinter/id/65/25.html
KevinBruce
2020/03/12
5570
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或者更准确的说,各种汇编指令都是在操作什么样的对象。
YGingko
2018/09/30
5610
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
本文转载地址:http://www.cnblogs.com/zuoxiaolong/p/computer14.html
YGingko
2018/09/30
4830
深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符
IAP的几个问题
这种情况应该得到重视,对于用户而言实际上是钱已经消费掉了,但是元宝或者物品没有获得,这会让人很焦虑的。的确,作为一名开发人员,遇到这种情况,第一反映确实是苹果出了问题,流程(逻辑)上没有什么问题,但是在苹果自己处理的那些步骤里,它可能就出异常了,导致了上面的问题。而我们实际上应该有相应的解决方案,哪怕它并不“完美”,总比二手一摊什么事不做要强很多吧
meteoric
2018/11/19
1.6K0
redis的几个问题
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/149
joshua317
2021/09/29
4340
用云函数快速批量处理COS里面的日志
本来CLS日志服务可以直接触发云函数来快速处理的,不过这样触发次数就有点多了,比如说被处理的日志本来就是云函数生成的,那么函数触发次数就直接要翻番,如果日志不是需要及时处理的话,可以让它在CLS里面累计上几分钟,然后用定时器触发一个云函数,通过日志服务查询接口 SearchLog 来实现批量处理。
黄希彤
2022/02/27
6140
深入理解计算机系统(3.1)------汇编语言和机器语言
IT可乐
2018/01/04
2K0
深入理解计算机系统(3.1)------汇编语言和机器语言
Win8下用DOSBox编写汇编语言
DOSBox 是一个 DOS模拟程序,可以很方便的移植到其他的平台,因此可以使用它在Win8系统中编写汇编语言。下面提供相关下载链接:
全栈程序员站长
2022/07/23
7210
Win8下用DOSBox编写汇编语言
5.1 汇编语言:汇编语言概述
汇编语言是一种面向机器的低级语言,用于编写计算机程序。汇编语言与计算机机器语言非常接近,汇编语言程序可以使用符号、助记符等来代替机器语言的二进制码,但最终会被汇编器编译成计算机可执行的机器码。
王瑞MVP
2023/10/11
6670

相似问题

汇编语言IA32中的游戏编程

24

如何在IA32汇编语言中获取位?

21

汇编语言IA32 -将char移动到int

14

不处理IA32异常?

10

用64位汇编语言编写函数

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文