64位NASM编程中的汇编编程基础 [英] Basics of Assembly programming in 64-bit NASM programming

查看:136
本文介绍了64位NASM编程中的汇编编程基础的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是汇编程序设计的新手,我试图解释以下代码,以打印出.data节中存在的数组: 这是代码:

I am new to assembly programming and trying to interpret the following code where I've to print an array present in the .data section : Here is the code:

%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


section .data

    msg db 10,"Array is : ",10
    len equ $-msg   

    array dq 11234H, 0AB32H, -3326H, 056BH

    newline db 10

section .bss

    buff resb 16;

section .code
global _start
_start:
    print msg,len
    mov rsi,array
    mov rcx,4
    back:
        mov rbx,[rsi]
        push rsi
        push rcx
        call HextoASCII
        print newline,1
        pop rcx
        pop rsi
        add rsi,8
    loop back

    exit


HextoASCII:
    mov rsi,buff
    mov rcx,16
    back1:
        rol rbx,4
        mov al,bl
        and al,0fh
        cmp al,9h
        jbe add_30h
        add al,7h
        add_30h:
            add al,30h

        mov [rsi],al
        inc rsi
    loop back1
    print buff,16
ret

我有几个问题想消除我的疑虑:

I have a few questions to ask to clear my doubts :

  1. .bss部分中存在的变量的默认值是多少?

  1. What is the default value of the variable present in the .bss section ?

味精的大小为10个字节(味精的最大大小),但是当我在其中添加更多字符时,即使字符串大小超过了其最大限制(10个字节),它仍会打印整个味精.

The size of msg is 10 bytes(max size of msg), but when I put more characters into it, then it still prints the entire msg even though the string size exceeds its maximum limit(10 bytes).

如果数组中给出的数字的最后一个(最高有效数字)非零,这并不意味着该数字为负数 即-数组中的11234H是否不是负数,因为我假设内存中最高有效位以1(FFF11234H)的形式出现.我认为对于非负数,其最高位数必须为零(011234),以便将较高位的位存储为0并使其为正数. 如果我在这里错了,那么要问的另一件事是FFFFFFFFH是-1还是大的正数.

If the numbers given in the array have their last(highest significant digit) as non-zero, doesn't it mean that the number is negative ie.- Isn't 11234H present in the array a negative number because I assume that the highest significant bits are present as 1 (FFF11234H) in the memory. I think that for a number to be non-negative its highest digit must be zero(011234), so that the higher ordered bits are stored as 0 in memory and make the number positive. If I'm wrong here then another thing to ask is whether FFFFFFFFH is -1 or a large positive number.

我对指令感到困惑

inc rsi

inc rsi

据说rsi加1.但是,这里的1是位或字节还是8字节(rsi的大小).

It is said that rsi is incremented by 1. But what is 1 here,bit or byte or 8 byte(size of rsi).

  1. 加30H或37H会将十六进制数字转换为39H或41H,它们是ASCII中9和A的十六进制表示形式,但我不明白为什么在显示器上打印39H或41H会产生结果9或A,并且而不是39H或41H本身.无论结果如何,汇编程序都会在监视器上打印等效的ASCII码.另外,我们通过汇编器/机器解释的键盘输入形式是什么,如果是ASCII,那么我是否需要将其显式转换回十六进制以便以后进行计算?

  1. Adding 30H or 37H converts the hexadecimal digit to 39H or 41H and these are hexadecimal representation of 9 and A in ASCII but I do not understand why printing 39H or 41H will yield the result 9 or A on my monitor and not 39H or 41H itself. Is it that whatever our result is, the assembler prints its ASCII equivalent on the monitor. Also, In what form is the input that we give through keyboard interpreted by assembler/machine and if it is ASCII then do I need to convert it back to HEX explicitly for later calculations ?

加30H或37H后,一位数字(0H-9H或AH-FH)被转换为两位数,范围从30H-39H和41H-46H,因此当我们将其移到buff时,不会它转换后实际上会占用buff数组元素大小的两倍以存储它吗?我假设之前的数字是4位,现在转换后是8位(9h是4位,而39h是8位).如果我错了,请纠正我. 如果我是对的,那是当每个数组元素大小仅为8个字节(四字)时buff被视为16个字节的原因.

After adding 30H or 37H,the single digit number(0H-9H or AH-FH) gets converted into double digit ranging from 30H-39H and 41H - 46H and so when we move this to buff, won't it actually occupy double the size of array element into buff to store it after the conversion ? I assume that earlier the digit took 4 bits and now it takes 8 bit after the conversion(9h is 4 bit and 39h is 8 bit). Do correct me, if I'm wrong here. If I'm right then, Is that the reason why buff is taken as 16 bytes when each array element size is just 8 bytes(quadword).

我了解HextoASCII的逻辑,该逻辑采用数字的最高位数并将其存储在buff中,然后继续进行,以后会打印buff,但不会以相反的方式打印数字,因为数组元素存储在buff的最低有效位置,并且随着rsi的增加,下一位将被添加到buff的较高位置,因此,如果我们打印buff,则最高有效数将被放置在buff.ie的最低有效位置. -12H在buff中存储为21,因为1首先存储在buff中,然后存储2.小尾数法和大尾数法在这里存储数字有什么重要性吗?如果是的话,请解释一下.

I understand the logic of HextoASCII which takes the highest digit of the number and stores it in buff and this goes on and later buff is printed but won't the number be printed in reverse manner because the highest digit of array element be stored at the least significant location of buff and as rsi is incremented the next digit will be added at the higher position of buff and so if we print buff then the most significant number gets placed at the least significant location of buff.ie-12H is store as 21 in buff because 1 is stored first in buff and later 2 is stored. Is there any importance of little endian and big endian here to store the digits ? Do explain, if yes.

在打印宏中,第二个参数始终是要打印的变量的大小.在这里,buff的大小为16个字节,因此第二个参数为16.但是如果我将第二个参数设为如果为8,那么为什么每个数组元素的一半数字没有被打印,而整个8位仍然被打印.另外,给我展示一种情况,其中将打印每个数组元素的一半数字,在这种情况下,将打印出较高的4位有效数字还是打印较低的4位有效数字?还有,为什么?

In the print macro, 2nd argument is always the size of the variable that is to be printed.Here, the size of buff is 16 bytes and hence the second argument is 16. But if I make the 2nd argument as 8 then why is half of the digits of every array element not being printed but still the entire 8 digits are getting printed. Also, present me a case where half of the digits of every element of array will be printed, In that case will the higher significant 4 digits be printed or the lower significant 4 digits be printed ? Also, why ?

推荐答案

  1. 零.
  2. 10不是msg的大小.这些只是嵌入式换行符.大小计算为len equ $-msg,因此将始终与您提供的文本的长度匹配.
  3. 根据大小,符号位是最高有效位.由于您有qword,因此11234H0000000000011234H并且是正数. FFFFFFFFH是一个很大的正数. FFFFFFFFFFFFFFFFH可以是更大的数字,也可以是-1,这取决于您将其解释为未签名还是已签名.
  4. 没什么,只是1.它只是将rsi中的值加一.以后用作地址时,这意味着1个字节.
  5. 那仅仅是因为您的终端使用ASCII码,因此将以30h的值显示0(依此类推).是的,如果您阅读文本,则需要从ascii转换为二进制.
  6. 那是正确的.
  7. 您正确地描述了它,但这并没有得到扭转.人类首先从最高有效数字开始.因此,将代码放在第一位然后递增rsi放在其他数字之后是有意义的.不知道为什么您会认为相反.
  8. 因为分别为每个数组元素调用print,因此缩短输出应用于每个元素而不是整个输出.当然,这将是较高的数字,因为这就是它们在内存中的方式.参见上面的第7点.
  1. Zero.
  2. 10 is not the size of msg. Those are just embedded line feeds. The size is calculated as len equ $-msg and thus will always match the length of the text you provide.
  3. The sign bit is the most significant bit according to the size. Since you have qwords, 11234H is 0000000000011234H and is positive. FFFFFFFFH is a large positive number. FFFFFFFFFFFFFFFFH could be an even larger number or -1, depending on whether you interpret it as unsigned or signed.
  4. Nothing, it's just 1. It's just adding one to the value in rsi. That will mean 1 byte when used as an address later.
  5. That's just because your terminal uses ascii codes and hence will print 0 for a value of 30h (and so on). Yes, you will need to convert from ascii to binary if you read text.
  6. That is correct.
  7. You described it correctly, but that is not reversed. Humans start with the most significant digit first. So it makes sense that the code puts that first and increments rsi to put the other digits after it. Not sure why you think that is reversed.
  8. Because print is invoked for each array element separately, hence shortening the output applies to each element not to the whole output. It will be the higher digits of course, since that's how they are in memory. See point 7, above.

这篇关于64位NASM编程中的汇编编程基础的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆