【问题标题】:Subtraction in x86 assemblyx86 汇编中的减法
【发布时间】:2016-05-01 21:39:53
【问题描述】:

我正在从教程点查看以下代码:

section .text
   global _start        ;must be declared for using GCC

_start:                 ;tell linker entry point
   sub     ah, ah
   mov     al, '9'
   sub     al, '3'
   aas
   or      al, 30h
   mov     [res], ax

   mov  edx,len         ;message length
   mov  ecx,msg         ;message to write
   mov  ebx,1           ;file descriptor (stdout)
   mov  eax,4           ;system call number (sys_write)
   int  0x80            ;call kernel

   mov  edx,1           ;message length
   mov  ecx,res         ;message to write
   mov  ebx,1           ;file descriptor (stdout)
   mov  eax,4           ;system call number (sys_write)
   int  0x80            ;call kernel

   mov  eax,1           ;system call number (sys_exit)
   int  0x80            ;call kernel

section .data
msg db 'The Result is:',0xa
len equ $ - msg
section .bss
res resb 1  

我觉得我理解这段代码,除了这行:

or al, 30h

我知道 or 是按位或,而 30h 是二进制的 0011 0000。我不明白为什么代码需要这样做!谁能给我解释一下?

【问题讨论】:

  • 它只是将 0..9 范围内的整数值(在本例中为 6)转换为其 ASCII 等效值 (0x36 = '6')。

标签: assembly x86 nasm


【解决方案1】:

这不是一个很好的例子。

减法后,al 包含 6。

aas 指令什么也不做,因为al 的高半字节为零。

0 的 ASCII 码是 30h。将其与 6 进行“或”运算会产生 36h,即 ASCII“6”。通常,这会将十进制数字的二进制值转换为其 ASCII 码。

听起来您将从研究二进制值与其 ASCII 表示之间的差异中受益。参见例如an ASCII table

但还要注意,此代码是 (AFAICS) 错误的,因为它将 16 位字存储到单个保留字节中。

【讨论】:

  • 啊我明白了....也许我应该学习更好的教程,你有什么建议吗?
  • @TylerHilbert:x86 tag wiki 中有一些链接,但大多数都是旧的(如 16 位 DOS)。标签 wiki 中有一个链接指向我写的关于学习 asm 的建议的答案。找一些你有兴趣玩弄的东西。也许从编译器输出开始,看看你是否通过尝试改变它来理解它。但听起来你的教程不是很好。在完全使用AAS 和只为一个保留空间后存储2B 之间,这听起来不像是一个很好的例子。
猜你喜欢
  • 1970-01-01
  • 2016-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多