【问题标题】:Convert byte to string in x86 assembly language在 x86 汇编语言中将字节转换为字符串
【发布时间】:2013-04-03 16:19:18
【问题描述】:

在 x86 汇编语言中,是否有任何有效的方法可以将字节转换为二进制数字字符串(表示为 0 和 1 的字节数组)?据我所知,在 x86 汇编中没有任何“toString”函数,就像在大多数高级编程语言中一样。

.stack 2048

.data
theString byte 0, 0, 0, 0, 0, 0, 0, 0 ;store eax as a binary string here.
ExitProcess proto, exitcode:dword 

.code
start:
mov eax, 3;
;now I need to convert eax to a binary string somehow (i. e., a byte array of 0s and 1s)
invoke  ExitProcess, 0
end start

【问题讨论】:

  • 至少可以从x86汇编语言的寄存器中获取第一位:stackoverflow.com/questions/15238467/…
  • 如果您的意思是转换,例如字符串“1101”的值 13 然后查看我对stackoverflow.com/questions/15786970/… 的回答它可以在 x86 上通过循环和SHL / JC 组合相当有效地完成。
  • @Michael 该问题讨论的是 MIPS 程序集而不是 x86 程序集。
  • 阅读实际答案。它绝不是 MIPS 特定的,甚至不包含任何 MIPS 代码。

标签: assembly x86 masm


【解决方案1】:

有那么难吗?:

.data
mystr db 33 dup(0)

.code

EaxToBinaryString:
    mov     ebx, offset mystr
    mov     ecx, 32
EaxToBinaryString1:
    mov     dl, '0' ; replace '0' with 0 if you don't want an ASCII string
    rol     eax, 1
    adc     dl, 0
    mov     byte ptr [ebx], dl
    inc     ebx
    loop    EaxToBinaryString1
    ret

【讨论】:

    【解决方案2】:

    使用 SSE 内在函数,可以这样编码:

    char in[2];
    char string[16];
    __m128i zeroes = _mm_set1_epi8('0');
    __m128i ones = _mm_set1_epi8('1');
    __m128i mask = _mm_set_epi8(
        0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1,
        0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1);
    __m128i val = _mm_set_epi8(
        in[1], in[1], in[1], in[1], in[1], in[1], in[1], in[1],
        in[0], in[0], in[0], in[0], in[0], in[0], in[0], in[0]);
    
    val = _mm_cmplt_epi8(val, _mm_and_si128(val, mask));
    val = _mm_or_si128(_mm_and_si128(val, zeroes), _mm_andnot_si128(val, ones));
    _mm_storeu_si128(string, val);
    

    代码执行以下步骤:

    • 将 2 字节输入复制到 XMM 寄存器的所有字节中,_mm_set1_epi...()
    • 创建掩码以从每个单词中提取不同的位
    • 位提取使用并行和
    • 将提取的位与掩码进行比较(低于)。
      如果该位被清除或设置,则结果是 0xffff0x0 的数组。
    • 使用该掩码提取'0''1' 字符,将它们组合起来。
    • 写出生成的字节数组

    这与移位和测试序列无关,但以_mm_set*() 为代价,每个扩展为几个 SSE 指令的序列。它仍然比位测试循环的 128 次迭代快。

    【讨论】:

    • 这是哪种汇编语言语法?我不认识它。 (我通常使用MASM语法,所以我现在有点困惑。)
    • 不是汇编 - 编译器 intrinsicssoftware.intel.com/en-us/articles/how-to-use-intrinsics
    • 即以上可以编译(使用C/C++编译器和#include <xmmintrin.h>);编译器将一些 SSE 内在函数替换为完全匹配的 SSE 指令(_mm_or... = POR_mm_cmplt... = PCMPGT 与反转操作数,...),其他的评估成一个小的指令序列(@ 987654334@ 个)。在许多情况下,首先使用内部函数编写和测试 x86 SIMD 代码会容易得多,然后在 ... 之后转储到普通/纯汇编函数中
    猜你喜欢
    • 1970-01-01
    • 2015-02-26
    • 2017-04-07
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多