NASM 中的汇编编程基础知识
Basics of Assembly Programming in NASM
我是汇编编程的初学者,想澄清一下我在解释这段代码时产生的一些疑惑
%macro print 2
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro exit 0
mov rax,60
mov rdi,0
syscall
%endmacro
%macro accept 2
mov rax,0
mov rdi,0
mov rsi,%1
mov rdx,%2
syscall
%endmacro
section .data
a dw 123AH
section .bss
b resb 2;
buff resb 2;
section .code
global _start
_start:
accept b,2
mov rsi,a ;3
mov rbx,[rsi] ;6
call hextoascii
mov rsi,buff
exit
hextoascii:
mov rcx,4
mov rsi,buff
back:
rol bx,4
mov al,bl
and al,0Fh
cmp al,09H
jbe add30h
add al,7h
add30h:
add al,30h
mov [rsi],al
inc rsi ;4
loop back
print buff,2 ;7
ret
我有几个问题想请教:
- 以下两者在内存或任何其他存储方面有什么区别吗
a) 一个 resb 2
b) 回复 1
- 如果我从用户那里接受一个变量,那么我必须为按下的 "Enter" 键保留另一个字节。是这样吗 ?如果是,那么 "Enter" 的 ascii 值是否会被连接为变量的最后一个字节?
指令:mov rsi,a (a=1234H)
rsi 指向 'a' 的哪个内存位置?即-它存储4的地址还是1的地址.
如果我递增 rsi 那么它会指向变量 a 的下一位吗?我该如何解释代码最后一行的 "inc rsi" ?
假设 rsi 当前指向 "a" 的基地址,它会增加多少位置?增量是否取决于它指向的变量的大小?
'a' 是如何出现在内存中的?即-相对于其他数字,1 出现在最低地址还是出现在最高地址?
在指令中:mov rbx,[rsi]
有多少 'a' 进入 rbx,rbx 可以在其中存储的 'a' 的最大限制是多少?
- 指令中:print buff,4
它只打印 'a' (12) 的一半值,而不是完全打印“1234”。我读过 print 宏的第二个参数应该是变量的大小(这里 'buff')但是由于 buff 的大小是 2 个字节,它只打印了一半而不是完整的。相反,如果我将 2 替换为 4,则会打印完整的“1234”。这里的大小是什么意思?是不是。字节数还是其他?
- 没有
- 是的。
- x86是little endian,所以第一个字节是最低有效字节,即
34h
.
- 不,一个十六进制数字是 4 位(半个字节)。你只能指向字节。
inc rsi
加 1,用作地址时为 1 个字节。
- 参见上文第 3 点。
- 由于您正在加载到
rbx
这是一个 64 位寄存器,这就是您将获得的数量。
- 要打印的文本的长度。代码已损坏,因为它将 4 个字节写入 2 个字节的缓冲区。
我是汇编编程的初学者,想澄清一下我在解释这段代码时产生的一些疑惑
%macro print 2
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro exit 0
mov rax,60
mov rdi,0
syscall
%endmacro
%macro accept 2
mov rax,0
mov rdi,0
mov rsi,%1
mov rdx,%2
syscall
%endmacro
section .data
a dw 123AH
section .bss
b resb 2;
buff resb 2;
section .code
global _start
_start:
accept b,2
mov rsi,a ;3
mov rbx,[rsi] ;6
call hextoascii
mov rsi,buff
exit
hextoascii:
mov rcx,4
mov rsi,buff
back:
rol bx,4
mov al,bl
and al,0Fh
cmp al,09H
jbe add30h
add al,7h
add30h:
add al,30h
mov [rsi],al
inc rsi ;4
loop back
print buff,2 ;7
ret
我有几个问题想请教:
- 以下两者在内存或任何其他存储方面有什么区别吗 a) 一个 resb 2 b) 回复 1
- 如果我从用户那里接受一个变量,那么我必须为按下的 "Enter" 键保留另一个字节。是这样吗 ?如果是,那么 "Enter" 的 ascii 值是否会被连接为变量的最后一个字节?
指令:mov rsi,a (a=1234H) rsi 指向 'a' 的哪个内存位置?即-它存储4的地址还是1的地址.
如果我递增 rsi 那么它会指向变量 a 的下一位吗?我该如何解释代码最后一行的 "inc rsi" ? 假设 rsi 当前指向 "a" 的基地址,它会增加多少位置?增量是否取决于它指向的变量的大小?
'a' 是如何出现在内存中的?即-相对于其他数字,1 出现在最低地址还是出现在最高地址?
在指令中:mov rbx,[rsi] 有多少 'a' 进入 rbx,rbx 可以在其中存储的 'a' 的最大限制是多少?
- 指令中:print buff,4 它只打印 'a' (12) 的一半值,而不是完全打印“1234”。我读过 print 宏的第二个参数应该是变量的大小(这里 'buff')但是由于 buff 的大小是 2 个字节,它只打印了一半而不是完整的。相反,如果我将 2 替换为 4,则会打印完整的“1234”。这里的大小是什么意思?是不是。字节数还是其他?
- 没有
- 是的。
- x86是little endian,所以第一个字节是最低有效字节,即
34h
. - 不,一个十六进制数字是 4 位(半个字节)。你只能指向字节。
inc rsi
加 1,用作地址时为 1 个字节。 - 参见上文第 3 点。
- 由于您正在加载到
rbx
这是一个 64 位寄存器,这就是您将获得的数量。 - 要打印的文本的长度。代码已损坏,因为它将 4 个字节写入 2 个字节的缓冲区。