本文介绍了乘两个值,并将其打印到屏幕(NASM和Linux)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继续读,为了让一个执行整数/浮点除法对寄存器,而在需要执行的寄存器(县)实际上是初始化。我很好奇,适当的汇编指令是做这算什么。我简单地通过类似提供一个地址:

MOV ECX,0x65F。0x65F重新presents地址为ECX指向

然后及时(后来在code)做这样的事情:

字节MOV [ECX],为0xA;移动是0xA值到ECX的内容,只使用一个字节的数据价值

这是要执行这样的操作的正确方法?如果没有,是什么?

更新

好了,所以我想要做的是乘法基本上两个值,并将其打印到屏幕上。
在code是如下,由于某种原因,每次我试图分裂 EDX 我得到无论是段错误或浮点算术异常。可能有人给我解释一下它是什么,我做错了?

code

 部分。数据
    计数器:DB是0xA;在反存储值10,只分配一个字节。这将用于递减的目的
.bss段
    valueToPrint:RESB 4;页头4个字节'valueToPrint数据.text段全球_start_print_char:
    添加EAX,'0';转换为ASCII
    MOV [valueToPrint],EAX;在valueToPrintEAX的商店内容
    MOV EAX,4; SYSWRITE
    MOV EBX,1;标准输出
    MOV ECX,valueToPrint;机器会采取任何的价值存在于ECX和打印
    MOV EDX,1,打印只是单字节的价值的数据
    0x80的诠释;调用内核亲热指令
    RET_convert_values​​:
    MOV EDX,为0xA;除以10,EAX,这将降低其十位
    DIV EDX;(这里**程序崩溃**)做除法:余应存放在EDX
    MOV字节[EDX],为0x0零出EDX
    呼吁_print_char;对于最新的字符做印刷
    十二月字节[计数器];递减计数器
    MOV DWORD [EAX],计数器;在EAX商场专柜
    JNZ _convert_values​​;而EAX> 0继续处理_endl:
    MOV EAX,'\\ n';在EAX店换行符被打印
    调用_print_char;打印值
    RET_mul:
    MOV EAX,0x2A;存储42 EAX
    MOV EDX,0x2B访问;存储43 EDX
    MUL EDX;乘法[EAX] * [EDX]
    RET_safe_exit:
    MOV EAX,1;启动退出系统调用
    MOV EBX,0;错误code 0退出
    0x80的诠释;调用内核来完成其投标_开始:
    NOP;用于保持GDB从抱怨    调用_mul;乘值
    调用_convert_values​​;做十六进制ASCII转换    JMP _safe_exit;使用JMP,而不是打电话,因为它在技术上不'RET'


解决方案

我们在聊天中谈到分开......

下面是一个工作版本一起玩。

它有一个微妙的问题。你可以找到它?
你能解释为什么它做什么呢?

 ;两个数相乘,显示ASCII /十进制
;
; (因为我有一个64位的系统,这迫使32位code)
        32位
;
        .text段
;
; _start是唯一的标签,您必须$ P $ _ PPEND
;其他人可能是库函数(例如:_printf,_exit)
;纯组装只需要_start,如果用glibc链接
;通常需要INSTEAD _main的_start
;
        全球_start
;
;
_开始:
        NOP;占位符GDB的调试中断
;
        调用MUL;乘值
        调用convert_values​​;做十六进制ASCII转换
;
        JMP safe_exit;使用JMP,而不是打电话,因为它在技术上不'RET'
;
;
;子程序/函数跟随
;
MUL:
        MOV EAX,0x2A;存储42 EAX
        MOV EDX,0x2B访问;存储43 EDX(42 * 43 = 1806)
        MUL EDX; EAX相乘* EDX,导致EDX:EAX
        RET
;
;这个程序不会处理从'MUL'伸入EDX BIG值
;我们正在学习,不要使事情繁衍到超过42十亿杂交
convert_values​​:
        MOV EDX,0;值实际上EDX:EAX,EDX零
        MOV ECX,0x0A的;鸿沟EDX:EAX 10
        IDIV ECX;导致EAX,余数在EDX
        推EAX;节省堆栈值
        MOV EAX,EDX;把其余的(0-9)在EAX
        添加EAX,'0';转换值的ASCII字符
        调用PRINT_CHAR;打印最新的性格
        弹出EAX;恢复值
        或EAX,EAX;根据EAX值设置标志
        JNZ convert_values​​;而EAX = 0继续处理!
;
; NASM不转换\\ n为进LF ......仅仅使用10,相当于
ENDL:
        MOV EAX,10;在EAX店换行符被打印
        调用PRINT_CHAR;打印值
        RET
;
PRINT_CHAR:
        MOV [valueToPrint],EAX;在EAX的商店内容[valueToPrint]
        MOV EAX,4; SYSWRITE
        MOV EBX,1;标准输出
        MOV ECX,valueToPrint;机器会采取任何价值[ECX]和打印存在
        MOV EDX,1,打印只是单字节的价值的数据
        0x80的诠释;调用内核亲热指令
        RET
;
safe_exit:
        MOV EAX,1;启动退出系统调用
        MOV EBX,0;错误code 0退出
        0x80的诠释;调用内核来完成其投标
;
; =====================================
        .bss段
;本节不分配,只保留。
;自动置零程序启动时
;
; ALLOC 4个字节'valueToPrint数据
valueToPrint:
        RESD 1; 1 RESD = 4 RESB(DWORD /字节)
;
;

I'm emailing this directly to you, along with some additional notes.

这篇关于乘两个值,并将其打印到屏幕(NASM和Linux)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 15:13