我正在努力学习NASM程序集,但我似乎正在努力解决高级语言中的问题.
我正在使用的所有教科书都使用字符串进行讨论 - 实际上,这似乎是他们最喜欢的东西之一.打印你好世界,从大写改为小写等
但是,我试图了解如何在NASM程序集中增加和打印十六进制数字,并且不知道如何继续.例如,如果我想在Hex中打印#1 - n,那么如果不使用C库(我能够找到使用的所有引用),我该怎么办呢?
我的主要想法是在.data部分有一个变量,我将继续增加.但是如何从此位置提取十六进制值?我似乎需要先将它转换为字符串......?
任何建议或示例代码将不胜感激.
我需要创建一个将内存地址转换为字节字符串的例程.那个字符串将成为打印以空字符结尾的字符串(我已经能够制作)的函数的输入.例如,如果我有一个地址0x1bf9,我需要将文本"1bf9"打印到屏幕上.这本书尚未进入32位模式,但有点暗示我们也需要它.这是我到目前为止:
TABLE:
db "0123456789ABCDEF", 0
STRING:
db 0
hex_to_char:
lea bx, TABLE
mov ax, dx
mov ah, al ;make al and ah equal so we can isolate each half of the byte
shr ah, 4 ;ah now has the high nibble
and al, 0x0F ;al now has the low nibble
xlat ;lookup al's contents in our table
xchg ah, al ;flip around the bytes so now we can get the higher nibble
xlat ;look up what we just flipped
inc …
Run Code Online (Sandbox Code Playgroud) 我从 NASM 的文档中看到了以下规则:
在进行调用之前,堆栈指针 %rsp 必须与 16 字节边界对齐。很好,但是进行调用的过程会将返回地址(8 个字节)压入堆栈,因此当函数获得控制权时,%rsp 未对齐。你必须自己创造额外的空间,通过推动某些东西或从 %rsp 中减去 8。
我有一段 NASM 汇编代码,如下所示:
在我调用“_start”中的函数“inc”之前,%rsp 应该位于 8 字节的边界,这违反了 NASM 文档中描述的规则。但实际上,一切都在进行中。那么,我如何理解这一点呢?
我是在 Ubuntu 20.04 LTS (x86_64) 下构建的。
global _start
section .data
init:
db 0x2
section .rodata
codes:
db '0123456789abcdef'
section .text
inc:
mov rax, [rsp+8] ; read param from the stack;
add rax, 0x1
ret
print:
lea rsi, [codes + rax]
mov rax, 1
mov rdi, 1
mov rdx, 1
syscall
ret
_start:
; enable AC check;
pushf
or …
Run Code Online (Sandbox Code Playgroud) 我知道字节混洗指令,但我想对半字节(4 位值)做同样的事情,具体来说,我想在 64 位字中混洗 16 个半字节。我的洗牌索引也存储为 16 个半字节。最有效的实施是什么?
我计划将X变量转换为十进制.我很难使用turbo汇编程序,你能帮忙吗?
code segment ;inicio de un segmento unico
assume cs:code,ds:code,ss:code
org 100h ;localidad de inicio del contador
main proc ;procedimiento principal
mov ax,cs
mov ds,ax ; INICIO
mov ax, x
mov ah,4ch ;comienzo del fin de programa
int 21h ;fin del programa
main endp
x dw 0A92FH
code ends ; fin del segmento de codigo
end main ;fin del ensamble
Run Code Online (Sandbox Code Playgroud)
非常感谢
我编写了一个汇编程序来显示遵循 AT&T 语法的数字的阶乘。但它不起作用。这是我的代码
.text
.globl _start
_start:
movq $5,%rcx
movq $5,%rax
Repeat: #function to calculate factorial
decq %rcx
cmp $0,%rcx
je print
imul %rcx,%rax
cmp $1,%rcx
jne Repeat
# Now result of factorial stored in rax
print:
xorq %rsi, %rsi
# function to print integer result digit by digit by pushing in
#stack
loop:
movq $0, %rdx
movq $10, %rbx
divq %rbx
addq $48, %rdx
pushq %rdx
incq %rsi
cmpq $0, %rax
jz next
jmp loop
next:
cmpq $0, %rsi …
Run Code Online (Sandbox Code Playgroud) 我是初学者,需要将 16 位二进制数转换为十六进制数的帮助。我已经完成了大部分代码,但我需要一些帮助。
输入示例:
1010101111001101
预期输出:
A B C D
电流输出:
AAAC
这是我的代码:
.MODEL SMALL
.STACK 1000h
.DATA
title db 'Convert BIN to HEX:.',13,10,'$'
HEX_Map DB '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
HEX_Out DB "00", 13, 10, '$' ; string with line feed and '$'-terminator
.CODE
main PROC
mov ax, @DATA ; Initialize DS
mov ds, ax
mov ah, 0
mov al, 3 ;clearing
int 10h
mov ah, 9
lea dx, title
int 21h ;displays title
mov dx, 0
loop16:
mov cx, 16 …
Run Code Online (Sandbox Code Playgroud) 这是我当前的代码:
//Input:hex string , 1234ABCDEEFF0505DDCC ....
//Output?BYTE stream
void HexString2Hex(/*IN*/ char* hexstring, /*OUT*/ BYTE* hexBuff)
{
for (int i = 0; i < strlen(hexstring); i += 2)
{
BYTE val = 0;
if (hexstring[i] < 'A')
val += 0x10 * (hexstring[i] - '0');
else
val += 0xA0 + 0x10 * (hexstring[i] - 'A');
if (hexstring[i+1] < 'A')
val += hexstring[i + 1] - '0';
else
val += 0xA + hexstring[i + 1] - 'A';
hexBuff[i / 2] = val;
} …
Run Code Online (Sandbox Code Playgroud) 有没有办法转换以下代码:
int mask16 = 0b1010101010101010; // int or short, signed or unsigned, it does not matter
Run Code Online (Sandbox Code Playgroud)
到
__uint128_t mask128 = ((__uint128_t)0x0100010001000100 << 64) | 0x0100010001000100;
Run Code Online (Sandbox Code Playgroud)
所以要特别清楚,比如:
int mask16 = 0b1010101010101010;
__uint128_t mask128 = intrinsic_bits_to_bytes(mask16);
Run Code Online (Sandbox Code Playgroud)
或直接敷面膜:
int mask16 = 0b1010101010101010;
__uint128_t v = ((__uint128_t)0x2828282828282828 << 64) | 0x2828282828282828;
__uint128_t w = intrinsic_bits_to_bytes_mask(v, mask16); // w = ((__uint128_t)0x2928292829282928 << 64) | 0x2928292829282928;
Run Code Online (Sandbox Code Playgroud) 我正在编写一个程序,将二进制值的十六进制表示转换为常规字符串.因此十六进制表示中的每个字符都将转换为字符串中的两个十六进制字符.这意味着结果将是两倍大小; 1字节的十六进制表示将需要字符串中的两个字节.
十六进制字符
0123456789 ;0x30 - 0x39
ABCDEF ;0x41 - 0x46
Run Code Online (Sandbox Code Playgroud)
例
0xF05C1E3A ;hex
4032568890 ;dec
Run Code Online (Sandbox Code Playgroud)
会成为
0x4630354331453341 ;hex
5057600944242766657 ;dec
Run Code Online (Sandbox Code Playgroud)
题?
是否有任何优雅/替代(/有趣)方法在这些状态之间进行转换,而不是查找表,(按位运算,移位,模数等)? 我不是在寻找库中的函数,而是如何实现/应该如何实现.有任何想法吗?