首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用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

复制
相关文章
Windows 窗体中的事件顺序
对于依次处理其中每个事件的开发人员,Windows 窗体应用程序中引发事件的顺序非常具有吸引力。 当出现需要谨慎处理事件的情况时(例如,在重绘窗体的某些部件时),有必要了解运行时引发事件的确切顺序。 本主题提供了应用程序和控件的生存期中几个重要阶段中的事件顺序的详细信息。 有关鼠标输入事件的顺序的特定详细信息,请参阅Windows 窗体中的鼠标事件。Windows 窗体中的事件的概述,请参阅事件概述。 有关事件处理程序的构成的详细信息,请参阅事件处理程序概述。
CNXY
2019/05/24
1.3K0
C#学习系列文章之Windows窗体应用程序003
紧接着上一篇文章,我已经学习了控制台的使用,以及创建不同应用的Helloworld程序,这一篇文章,我介绍Windows窗体应用程序的简单实用,按照调用流程一步一步的操作,希望能帮助初学者也能一步一步的搭建起自己的第一个应用。由于本人水平有限,文章中难免有介绍不足的地方,敬请谅解。
算法发
2020/01/16
1.9K0
C#学习系列文章之Windows窗体应用程序003
windows窗体线程异常_指针在声明和使用时有何不同
大家好,又见面了,我是你们的朋友全栈君。 在多线程设计中,许多人为了省事,会将对话框类或其它类的指针传给工作线程,而在工作线程中调用该类的成员函数或成员变量等等。 但是在Debug版本时,在某些情况下,特别是在工作线程中调用pWnd->UpdateData(FALSE)时,会出现错误。 这个错误的原因网上有许多地方讲到了,但是,令人失望的是,讲得好的没几篇,都是非要讲什么线程模块状态什么的,让人看得云里雾里(不过,说实话,也就是从这些文章中才知道是怎么回事的)。
全栈程序员站长
2022/10/04
5310
WinForm之窗体应用程序
WinForm之窗体应用程序 基本简单数据库操作(增删改查) 1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 5 namespace DataBaseOperation 6 { 7 static class Program 8 { 9 /// <summary> 10 /// 应用程序的主入口点。 11 /
用户1112962
2018/07/04
1.3K0
在Office应用中打开WPF窗体并且让子窗体显示在Office应用上
在.NET主程序中,我们可以通过创建 ExcelApplication 对象来打开一个Excel应用程序,如果我们想在Excle里面再打开WPF窗口,问题就不那么简单了。 我们可以简单的实例化一个WPF窗体对象然后在Office应用程序的窗体上打开这个新的WPF窗体,此时Office应用的窗体就是WPF的宿主窗体。然后宿主窗体跟Office应用并不是在一个UI线程上,子窗体很可能会在宿主窗体后面看不到。这个时候需要调用Win32函数,将Office应用的窗体设置为WPF子窗体的父窗体,这个函数的形式定义如下
用户1177503
2018/05/03
1.7K0
C# 窗体常用API函数 应用程序窗体查找
常用的处理窗体的API函数如下(注意:API函数必须放在窗体中...): 使用C#语言,要引用DllImport,必须要添加using System.Runtime.InteropServices命名空间 (1)获得当前前台窗体句柄 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]public static extern IntPtr GetForegroundWindow(); 返回值类型是IntPtr,即为当前
逸鹏
2018/04/10
4K0
创建可调大小的用户窗体——使用Windows API
在使用VBA创建用户窗体时,通常会将其设置为特定的大小。然而,通过一些编码技巧,可以为其实现类似的调整大小效果。
fanjy
2023/08/29
4840
创建可调大小的用户窗体——使用Windows API
Excel用户窗体中添加最小化按钮及窗体最小化的代码实现
文章背景:用户窗体是Excel中的UserForm对象。在使用UserForm时,曾经目前遇到过两个问题。
Exploring
2022/08/10
2.5K0
Excel用户窗体中添加最小化按钮及窗体最小化的代码实现
窗体应用程序防腾讯QQ源码
窗体应用程序防腾讯QQ源码 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 using Aptech.UI; 9 using System.Data.SqlCli
用户1112962
2018/07/04
1.7K0
windows 任何应用程序在 运行 里直接打开
    很多时候电脑的桌面 应用 icon 很多了,不方便找到也比较浪费时间,还有 有些 应用 icon 也许不想放在桌面上,如果能用命令方式打开 应用 那该多好。
卓越笔记
2023/02/18
9340
windows 任何应用程序在 运行 里直接打开
在Windows Mobile上隐藏你的应用程序
    有时候,我们需要在Windows Mobile上做一些invisible的应用程序,使得用户无法察觉。这几天找了一些资料,请教了Jake等一些朋友,下面就做一个简单的总结。 1. 如何逃脱“任
ShiJiong
2018/01/10
1.2K0
在Windows Mobile上隐藏你的应用程序
创建可维护和可测试的 Windows 窗体应用程序的 10 种方法(译)
我遇到的大多数 Windows 窗体应用程序都不存在或单元测试覆盖率极低。而且它们通常也很难维护,项目中各种 Form 类的代码背后有数百甚至数千行代码,但它不必是这样。仅仅因为 Windows 窗体是一项“遗留”技术,并不意味着你注定会造成无法维护的混乱。下面是创建可维护和可测试的 Windows 窗体应用程序的十个技巧。
沙漠尽头的狼
2021/12/15
1.3K0
Java Swing中的透明窗体(Windows中消息提示框的制作)
首先需要在工程中导包,需要用到JRE中的rt.jar包,我的JDK安装在C盘,目录如下:C:\Program Files\Java\jre7\lib\rt.jar。
卡尔曼和玻尔兹曼谁曼
2019/01/25
2.2K0
在Excel中创建悬浮图
步骤1:根据原始数据,整理用于创建图表的数据,如下图2所示。一个名为“隐藏”的列,计算出悬浮的高度,也就是前面显示的柱状的高度之后;一个名为“显示”的列,即绘制的可见柱状的高度。
fanjy
2023/10/05
6840
在Excel中创建悬浮图
Windows窗体应用类型的差异区别
最近在写小工具的时候,遇到一个坑点,项目的Debug/Release目录下一直有一个文件:项目名.runtimeconfig.json,还无法删除!删除了exe就跑不起来。
meteoric
2023/01/13
9300
Windows窗体应用类型的差异区别
使用ProcDump工具解决Windows应用程序崩溃
ProcDump是一个可以用于诊断多种问题点的命令行工具。和Dr.Watson、ADPlus以及DebugDiag一样,ProcDump可以在不期望的情况或者异常发生时,用于俘获一个进程的内存转储。而且也同ADPlus以及DebugDiag一样,它可以对一个挂起的应用程序强制进行进程转储。但和之前的任何工具不同的是,ProcDump可以在CPU的活动峰值达到一个指定的级别时,对一个进程进行转储。这对于那些间歇性的性能问题是特别有用的,对于这种问题,其发生是很难预测的。 ProcDump包括一个单独的可执行
张善友
2018/01/29
2.9K0
【VBA】在excel中检索文本
虽然在excel文件中检索的vba代码不知道写了多少遍了,每次需要的时候,都是从网上找,然后写。实在是低效的做法。从网上找了一段代码,放在此处,以后需要的时候可以随手拿来。
东风压倒西风
2022/09/06
2.9K0
在Excel中创建瀑布图
在Excel中很容易创建瀑布图,因为自Excel 2016就推出了瀑布图。然而,改变瀑布颜色稍微有点困难。
fanjy
2023/08/30
7230
在Excel中创建瀑布图
在Windows中劫持DLL
DLL劫持是一种用于执行恶意有效负载的流行技术,这篇文章列出了将近300个可执行文件,它们容易受到Windows 10(1909)上相对路径DLL劫持的攻击,并展示了如何使用几行VBScript绕过UAC可以以提升的特权执行某些DLL劫持。
Al1ex
2021/07/21
2.2K0
在Windows中劫持DLL
windows 应用程序在关机时的退出代号
在 windows 应用程序关闭的时候可以通过进程的 ExitCode 了解这个应用是如何关闭的
林德熙
2019/03/13
1.3K0

相似问题

如果模型不实现INotifyPropertyChanged,视图模型如何从其底层模型传播更改通知?

20

如何提取底层模型对象?

18

通知模型/模式

20

如何通知模型/视图底层数据更改了表标题?

11

如何引用django模型表单对象的底层模型?

21
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文